稍微复杂的多对多linq查询让我卡住了



所以我在Linq-To-Entities与asp.net mvc项目

我总是被这类问题难住了。

我的schema是:

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()断章取义。

此计算不转换为SQL,因为它不是字符串/guid或int。

您需要在查询中查询该对象并从该对象求值。

我不确定这是否清楚。

你需要做一些像

var query1 = (from x in tags where x.tagID = id select x.ProductNames)
                                                          .SelectMany(...)

选择许多是因为您正在选择一个集合ProductNames,并且需要将其作为一个平面集合/集合带回来,以便您可以在下一个查询中对其执行.Any()

然后使用这个,并做一个query1.Any(logic)

decimal total = myentities.PurchaseRecords.
                           Where(x => query1.Any
                                (a => a.FullName == x.ProductName.FullName))
                                .Sum(s => s.Amount); 

通过这样做,你将保持到实体的linq,而不是转换到对象的linq。

ForEach不是一个选项,因为它将遍历集合。

你可以在c#中使用AsEnumerable方法来执行查询的某些部分,而不是在sql server上。当内存中有部分数据(对象集合)时,通常需要这样做,因此在查询中使用它们并不容易。你必须在。net端执行部分查询。对于您的问题,请尝试

decimal total = myentities.PurchaseRecords.AsEnumerable()
                    .Where(x => thetag.ProductNames.Any
                         (a => a.FullName == x.ProductName.FullName))
                         .Sum(s => s.Amount);

请访问此链接了解更多关于

相关内容

  • 没有找到相关文章

最新更新