稍微复杂的多对多 linq 查询让我陷入困境
所以我正在使用一个 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);
So I'm on Linq-To-Entities with an asp.net mvc project.
I always get a little stumped with this sort of query.
My schema is:
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.
I need to get the sum of all purchases for a given tag.
This is what I've tried.
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);
I've tried changing a couple of things, tried using Contains
, but I know I'm fundamentally wrong somewhere.
I keep getting :
Unable to create a constant value of type 'ProductName'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
Update
So with @Alexandre Brisebois's help below it worked simply like this:
var total= item.ProductNames.SelectMany(x => x.PurchaseRecords)
.Sum(s => s.Amount);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当出现此类错误时,您需要在 linq 查询之外进行所有计算,并将值作为变量传递。
您的查询的问题是
thetag.ProductNames.Any()
脱离了上下文。此评估不会转换为 SQL,因为它不是字符串/guid 或 int。
您将需要在查询中查询该对象并根据该对象进行评估。
我不确定这是否清楚。
您需要执行类似
“选择很多”的操作,因为您正在选择一个集合
ProductNames
,并且需要将其作为平面集/集合返回,以便您可以执行.Any()
在下一个查询中对其进行处理。然后使用它并执行
query1.Any(logic)
通过执行此操作,您将保留在 linq to 实体中,而不是转换为 linq to 对象。
ForEach
不是一个选项,因为这将迭代集合。When you get this sort of error, you need to do all evaluations outside of the linq query and pass the values in as variables.
the problem with your query is that
thetag.ProductNames.Any()
is out of context.This evaluation is not converted to SQL since it is not a string/guid or int.
You will need to query for this object within your query and evaluate from this object.
I'm not sure if that was clear.
You would need to do something like
The select many is because you are selecting a collection
ProductNames
and need to bring it back as a flat set/collection fo that you can do a.Any()
on it in the next query.Then use this and do an
query1.Any(logic)
By doing this you will stay in linq to entity and not convert to linq to objects.
The
ForEach
is not an option since this will iterate over the collection.您可以使用 AsEnumerable 方法在 C# 中而不是在 sql server 上执行查询的某些部分。当内存中有部分数据(对象集合)时通常需要这样做,因此在查询中使用它们并不容易。您必须在 .net 端执行部分查询执行。对于您的问题,请尝试
访问此链接 查找有关 AsEnumerable 的更多信息
you can use AsEnumerable method to perform certain portions of query in C# rather than on sql server. this is usually required when you have part of data in memory (Collection of objects) so using them in query is not easy. you have to perform part of query execution on .net side. for your problem plz try
plz visit this link to find more about AsEnumerable