我正在使用C#和.NET Framework 4.5.1,使用Entity Framework 6.1.3从SQL Server数据库中检索数据。
我有这个:
codes = codesRepo.SearchFor(predicate)
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
当我运行它时,我得到这样的消息:
LINQ to Entities中只支持无参数构造函数和初始值设定项。
我不知道如何创建元组,因为我找到的所有示例都与此类似。
我试过这个:
codes = codesRepo.SearchFor(predicate)
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
得到这个错误:
LINQ to Entities无法识别方法“System.Tuple`2[System.String,System.Byte] Create[String,Byte](System.String,Byte)”方法,并且此方法无法转换为存储表达式。
问题出在哪里?
7条答案
按热度按时间cbeh67ev1#
虽然octavioccl的答案是可行的,但最好先将查询结果投影到匿名类型,然后切换到enumerable并将其转换为元组。这样,您的查询将只从数据库中检索所需的字段。
**注:**以上规则适用于EF 6。EF Core通过元组构造器自然地支持元组(在投影中或作为连接/组键),例如原始查询仅起作用
而不是
Tuple.Create
方法(EF Core 2.x)。bqf10yzr2#
这只是C# 7的更新答案,现在您可以使用更简单的语法来创建ValueTuples。
现在你甚至可以命名元组的属性:
因此,您可以作为Id或Flag访问它,而不是将其用作Item1或Item2。
更多关于choosing-between-anonymous-and-tuple的文档
jdzmm42g3#
试试这个:
已被告知这在LINQ to实体中不接受。
另一种选择是在选择之前将结果拉入内存。如果你要这样做,我建议你在.AsEnumerable()之前完成所有的过滤,因为这意味着你只会拉回你想要的结果,而不是拉回整个表然后过滤。
如果您想让代码在元组类型中更显式一些,Tuple.Create(c.Id,c.Flag)也可以更改为newTuple(c.Id,c.Flag)
mf98qq944#
在linq to entities中,你可以投影到匿名类型或DTO上。为了避免这个问题,你可以使用
AsEnumerable
扩展方法:这个方法可以让你使用Linq to Object而不是Linq to Entities,所以在调用它之后,你可以在任何你需要的地方投影你的查询结果。使用
AsEnumerable
而不是ToList
的好处是AsEnumerable
不执行查询,它保留了延迟执行。在调用这些方法之前,最好先过滤数据。b5lpy0ml5#
使用此方法来执行此操作并使用异步。
iaqfqrcu6#
我的两分钱:这让我在类型名称上遇到了几次麻烦:
举几个简单的例子:
问候。
p5fdfcr17#
您也可以使用
record
。https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records
那就像
稍后,您可以使用命名属性而不是.Item1、.Item2