[英]Projecting into KeyValuePair via EF / Linq
I'm trying to load a list of KeyValuePairs from an EF / Linq query like this:我正在尝试从 EF / Linq 查询加载 KeyValuePairs 列表,如下所示:
return (from o in context.myTable
select new KeyValuePair<int, string>(o.columnA, o.columnB)).ToList();
My problem is that this results in the error我的问题是这会导致错误
"Only parameterless constructors and initializers are supported in LINQ to Entities." “实体的 LINQ 中仅支持无参数构造函数和初始值设定项。”
Is there an easy way around this?有没有简单的方法解决这个问题? I know I could create a custom class for this instead of using KeyValuePair but that does seem like re-inventing the wheel.我知道我可以为此创建一个自定义 class 而不是使用 KeyValuePair 但这看起来确实像是在重新发明轮子。
Select only columnA and columnB from your table, and move further processing in memory: 从表中仅选择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();
Consider also to create dictionary which contains KeyValuePairs: 还要考虑创建包含KeyValuePairs的字典:
return context.myTable.ToDictionary(o => o.columnA, o => o.columnB).ToList();
Since LINQ to Entities does not support KeyValuePair
, you should turns to LINQ to Object by using AsEnumerable
first: 由于LINQ to Entities不支持KeyValuePair
,因此您应首先使用AsEnumerable
转向LINQ to Object:
return context.myTable
.AsEnumerable()
.Select(new KeyValuePair<int, string>(o.columnA, o.columnB))
.ToList();
With recent versions of EF Core selecting into KeyValuePair appears to work fine.使用最新版本的 EF Core 选择 KeyValuePair 似乎工作正常。 I also verified that (on MS SQL Server) the SQL only selects the two relevant fields, so the "Select" is actually translated:我还验证了(在 MS SQL 服务器上)SQL 只选择了两个相关字段,所以“选择”实际上是翻译的:
return context.myTable
.Select(x => new KeyValuePair<int, string>(o.columnA, o.columnB))
.ToList();
SELECT [m].[columnA], [m].[columnB]
FROM [myTable] AS [m]
The generated SQL is the same as for anonymous classes, except that renames are only made for the latter ("eg AS A"):生成的 SQL 与匿名类相同,只是重命名仅为后者(“例如 A”):
return context.myTable
.Select(x => new {A = o.columnA, B = o.columnB})
.ToList();
SELECT [m].[columnA] AS [A], [m].[columnB] AS [B]
FROM [myTable] AS [m]
Tested with .NET 6.用 .NET 6 测试。
Note that using a Dictionary (as suggested in other answers) will introduce additional constraints compared to a List of KeyValuePairs:请注意,与 KeyValuePairs 列表相比,使用字典(如其他答案中所建议的那样)会引入额外的约束:
Depending on the use case of the OP (which I cannot deduce from the question), some of these constraints might be desirable, though, and the Dictionary might actually be the solution.根据 OP 的用例(我无法从问题中推断出),其中一些约束可能是可取的,而 Dictionary 实际上可能是解决方案。
There is also alternative, when you want to store multiple values for one key exists something what is called Lookup . 还有另一种选择,当你想为一个键存储多个值时,存在一个叫做Lookup的东西。
Represents a collection of keys each mapped to one or more values. 表示每个映射到一个或多个值的键集合。
Here you have some official documentations . 这里有一些官方文件 。
More over lookup seems to be much faster than Dictionary < TKey, List < TValue > >. 更多的查找似乎比Dictionary <TKey,List <TValue >>快得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.