问题描述
||
因此,我使用asp.net mvc项目在Linq-To-Entities上。
我总是对这种查询有些困惑。
我的架构是:
ProductTag
+TagName
+<<ProductNames>>//Many-to-many relationship
ProductName
+FullName
+<<Tag>>//Many-to-many relationship
PurchaseRecord
+Amount
+<<ProductName>>//one productname can be linked to Many purchase records.
我需要获取给定标签的所有购买金额之和。
这就是我尝试过的。
ProductTag thetag//Could be some tag
decimal total = myentities.PurchaseRecords
.Where(x => thetag.ProductNames.Any
(a => a.FullName == x.ProductName.FullName))
.Sum(s => s.Amount);
我已经尝试过更改一些事情,尝试使用Contains
,但是我知道我在某处根本上是错误的。
我不断得到:
无法创建\'ProductName \'类型的常量值。在此上下文中仅支持基本类型(\',例如Int32,String和Guid \')。
更新资料
因此,在下面的@Alexandre Brisebois的帮助下,它的工作原理如下:
var total= item.ProductNames.SelectMany(x => x.PurchaseRecords)
.Sum(s => s.Amount);
解决方法
遇到这种错误时,您需要在linq查询之外进行所有评估,并将值作为变量传递。
您查询的问题是
thetag.ProductNames.Any()
不在上下文中。
此评估不是字符串/ guid或int,因此不会转换为SQL。
您将需要在查询中查询该对象,然后从该对象进行评估。
我不确定是否很清楚。
您需要做类似的事情
var query1 = (from x in tags where x.tagID = id select x.ProductNames)
.SelectMany(...)
选择很多是因为您正在选择一个集合ѭ6,并且需要将其作为一个平面集/集合带回去,您可以在下一个查询中对其进行一个.Any()
。
然后用它做一个query1.Any(logic)
decimal total = myentities.PurchaseRecords.
Where(x => query1.Any
(a => a.FullName == x.ProductName.FullName))
.Sum(s => s.Amount);
这样,您将停留在linq to实体中,而不会转换为linq to objects。
不能选择“ 10”,因为这会遍历整个集合。
,您可以使用AsEnumerable方法在C#中而不是在SQL Server上执行查询的某些部分。当内存中有部分数据(对象的集合)时,通常需要这样做,因此在查询中使用它们并不容易。您必须在.net端执行部分查询执行。对于您的问题请尝试
decimal total = myentities.PurchaseRecords.AsEnumerable()
.Where(x => thetag.ProductNames.Any
(a => a.FullName == x.ProductName.FullName))
.Sum(s => s.Amount);
请访问此链接以找到有关AsEnumerable的更多信息