[英]How to do join with objects in Entity Framework
因此,我正在使用实体框架将具有普通SQL查询的旧项目转换为ORM。 所以我创建了这样的数据库模型:
所以我有这个旧的查询,我想转换为linq表达式
SELECT UGLINK.USERNAME
FROM GMLINK
INNER JOIN UGLINK
ON GMLINK.GROUPID = UGLINK.GROUPID
WHERE (((GMLINK.MODULEID)=%ID%))
我遇到的问题是我无法弄清楚如何使用对象进行连接查询。 相反,我必须通过这样的属性(似乎工作):
// So this is one of the module objects that is located in a listView in the GUI
Module m = ModuleList.selectedItem as Module;
/* Now I want to fetch all the User objects that,
* via a group, is connected to a certain module */
var query = context.gmLink
.Join(context.ugLink,
gmlink => gmlink.GroupId,
uglink => uglink.GroupId,
(gmlink, uglink) => new { gmLink = gmlink, ugLink = uglink })
.Where(gmlink => gmlink.gmLink.ModuleId == m.ModuleId)
.Select(x => x.ugLink.User);
正如我所说的那样有效,但正如你所看到的那样,我必须通过链接表属性.GroupId
和.ModuleId
等连接模块。 相反,我想通过EF创建的对象。
我想写一个类似这样的问题,但无法弄清楚如何做到这一点,它是否可能?
var query = context.User
.Select(u => u.ugLink
.Select(uglink => uglink.Group.gmLink
.Where(gmLink => gmLink.Module == m)));
如果启用了延迟加载,则不需要应用特定的连接表示法(可以直接访问导航属性) - 但针对SQL运行的查询效率低下(通常结果会在许多不同的select语句中返回) 。
我的偏好是在上下文中禁用延迟加载,并使用.Include()表示法手动将表连接在一起,从而通常可以提高查询效率。 .Include()用于显式连接Entity Framework中的实体。
Join()具有误导性,不适合在EF中连接表。
所以,要复制这个声明:
SELECT UGLINK.USERNAME
FROM GMLINK
INNER JOIN UGLINK
ON GMLINK.GROUPID = UGLINK.GROUPID
WHERE (((GMLINK.MODULEID)=%ID%))
您将使用以下内容:
var query = context.gmLink
.Include(x => x.Group.gmLink)
.Where(x => x.ModuleId == myIdVariable)
.Select(x => new {
UserName = x.Group.ugLink.UserName
});
假设您的导航属性已正确设置。 我没有测试过这个,所以我不是100%的语法。
在编写和运行针对数据库的LINQ to Entity查询时,您应该真正运行SQL事件探查器,这样您就可以了解实际生成的内容并针对您的数据库运行。 很多时候,EF查询可能正常运行,但在部署到生产系统时可能会遇到性能问题。
本白皮书可能会帮助您。
这应该是有效的:
var query = context.gmLink
.Where(gmlink => gmlink.ModuleId == m.ModuleId)
.SelectMany(gmlink => gmlink.Group.ugLink)
.Select(uglink => uglink.User);
在EF中使用.Where(gmlink => gmlink.Module == m)
过滤gmLink是不可能的,因此需要使用标识符进行比较。 另一个选项是.Where(gmlink => gmlink.Module.ModuleId == m.ModuleId)
我还没有测试过,但是这样的话:
var users = context.User
.Where(x => x.ugLink
.Any(y => context.gmLink
.Where(z => z.ModuleId == m)
.Select(z => z.GroupId)
.Contains(y.GroupId)
)
)
.ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.