【问题标题】:Projecting into KeyValuePair via EF / Linq通过 EF / Linq 投影到 KeyValuePair
【发布时间】:2013-06-22 12:34:25
【问题描述】:

我正在尝试从 EF / Linq 查询中加载 KeyValuePairs 列表,如下所示:

return (from o in context.myTable 
select new KeyValuePair<int, string>(o.columnA, o.columnB)).ToList();

我的问题是这会导致错误

"只支持无参数的构造函数和初始化器 LINQ to Entity。”

有没有简单的方法解决这个问题?我知道我可以为此创建一个自定义类,而不是使用 KeyValuePair,但这似乎是在重新发明轮子。

【问题讨论】:

标签: c# linq entity-framework projection keyvaluepair


【解决方案1】:

还有另一种选择,当您想为一个键存储多个值时,存在称为 Lookup 的东西。

表示一组键,每个键映射到一个或多个值。

这里有一些官方的documentations

lookup 似乎比 Dictionary > 快得多。

【讨论】:

    【解决方案2】:

    从表中仅选择 columnA 和 columnB,然后在内存中进行进一步处理:

    return context.myTable
                  .Select(o => new { o.columnA, o.columnB }) // only two fields
                  .AsEnumerable() // to clients memory
                  .Select(o => new KeyValuePair<int, string>(o.columnA, o.columnB))
                  .ToList();
    

    还考虑创建包含 KeyValuePairs 的字典:

    return context.myTable.ToDictionary(o => o.columnA, o => o.columnB).ToList();
    

    【讨论】:

    • 注意:之所以这样是因为 LINQ-to-Entities 只支持无参数构造函数,所以你不能使用new KeyValuePair...。 LINQ-to-Collections 确实支持带参数的构造函数。当您调用 AsEnumerable() 时,它会评估 EF 查询,然后是 LINQ-to-Collections 处理以下 .Select()
    • 如何实现它的 ASYNC 版本?没有AsEnumerableAsync() 方法。
    • @Zapnologica - 将AsEnumerable() 替换为ToListAsync(),然后将await 用括号括到ToListAsync 的末尾,并根据需要附加.Select(o =&gt; new KeyValuePair&lt;int, string&gt;(o.columnA, o.columnB)).ToList(); 重构。
    【解决方案3】:

    由于 LINQ to Entities 不支持KeyValuePair,您应该首先使用AsEnumerable 转向 LINQ to Object:

    return context.myTable
                  .AsEnumerable()
                  .Select(new KeyValuePair<int, string>(o.columnA, o.columnB))
                  .ToList();
    

    【讨论】:

    • 虽然这行得通,但效率很低,因为它会从 myTable 加载所有列
    • .Select(o=> new KeyValuePair(o.columnA, o.columnB))
    猜你喜欢
    • 2019-12-15
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 2011-01-09
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多