我有三张桌子:
Materials :
-
ID
-
Headers
-
内容
Likes :
-
ID
-
MaterialID
-
UserID
-
IsLiked
Visitors :
-
ID
-
UserID
-
MaterialID
-
日期
-
ReadNow
我想得到一个像这样的对象:
-
Headers
-
内容
-
CountLikes
-
CountVisitors
我试着做以下事情:
from mat in ctx.materials
let visitors = mat.VisitorsCollection.Where(x=>x.ReadNow).Count()
let likes = mat.LikesCollection.Where(x=>x.IsLiked).Count()
let iliked = mat.LikesCollection.Where(x=>x.UserID == myID && x.IsLiked).Any()
select new {
Material = mat,
Visitors = visitors,
Likes = likes,
Liked = iliked
}
我获得了一些材料,并且实体框架分别接收了访问者数量等数据 .
我也尝试了以下内容:
from mat in ctx.materials
join lik in ctx.Likes.Where(x=>x.UserID == myID && x.IsLiked) on map.ID equals lik.MaterialID
select new {
Material = mat,
Liked = lik.Any()
}
但现在出现错误:
Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式'Any()'无法翻译,将在本地进行评估 .
2 回答
好吧,如果你在数据库中有外键,那么EF会在对象之间生成链接,所以你需要做的就是:
语法可能并不完全正确,但你明白了......
如果您使用的是实体框架,请考虑使用ICollections,而不是自己执行连接 .
你有一个
Materials
的序列,其中每个Material
都有零个或多个Likes
和零个或多个Visitors
,两个一对多的关系,使用Material
的外键 .如果您已经按照entity framework code first conventions进行操作,那么您将拥有类似于以下内容的类
喜欢和访客:
这就是实体框架需要检测一对多关系的所有内容 . 可能是您需要不同的表名称或列的不同标识符 . 在这种情况下,需要属性或流畅的API
一旦正确获得了类定义,您的查询就会非常简单直观:
需求:
用文字表示:从我完整的材料集合中,只保留那些......从每个剩余的材质中创建一个新对象:
Headers 是材料的 Headers
内容是材料的内容
LikeCount是此材料的喜欢数量(具有真正的IsLiked)
NrOfVisitors是此材料的访客数量(即...)
实体框架知道您的关系,并知道需要GroupJoin .