Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在实体框架中连接对象_C#_Sql_Linq_Entity Framework - Fatal编程技术网

C# 如何在实体框架中连接对象

C# 如何在实体框架中连接对象,c#,sql,linq,entity-framework,C#,Sql,Linq,Entity Framework,因此,我正在使用实体框架将带有普通SQL查询的旧项目转换为ORM。因此,我创建了如下数据库模型: var users = context.User .Where(x => x.ugLink .Any(y => context.gmLink .Where(z => z.ModuleId == m) .Select(z => z.GroupId)

因此,我正在使用实体框架将带有普通SQL查询的旧项目转换为ORM。因此,我创建了如下数据库模型:

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();

所以我有一个旧的查询,我想把它转换成一个linq表达式

SELECT UGLINK.USERNAME 
FROM GMLINK 
INNER JOIN UGLINK 
ON GMLINK.GROUPID = UGLINK.GROUPID 
WHERE (((GMLINK.MODULEID)=%ID%))
我的问题是,我不知道如何使用对象进行连接查询。 相反,我必须通过这样的属性(这似乎是可行的):

正如我所说,这是可行的,但正如您所看到的,我必须通过链接表属性
.GroupId
.ModuleId
等来连接模块。相反,我想浏览EF创建的对象

我想写一个有点像这样的问题,但不知道怎么做,有可能吗

var query = context.User
            .Select(u => u.ugLink
                .Select(uglink => uglink.Group.gmLink
                    .Where(gmLink => gmLink.Module == m)));

我还没有测试过,但类似这样:

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();

如果启用了延迟加载,则不需要应用特定的连接表示法(您可以直接访问导航属性),但是针对SQL运行的查询效率很低(通常结果在许多不同的select语句中返回)

我的首选是禁用上下文上的延迟加载,并使用.Include()表示法手动将表连接在一起,从而产生通常更高效的查询。Include()用于显式连接实体框架中的实体

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 profiler,这样您就可以了解实际生成的内容并对数据库运行这些查询。很多时候,EF查询可能运行正常,但部署到生产系统时可能会遇到性能问题


可能会帮助您解决问题。

这应该可以:

// 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);
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)

好的,除了m必须被m.ModuleId替换外,这是有效的,所以在某种意义上这比我的尝试更好,但是它仍然连接
.ModuleId
.GroupId
即原语而不是对象(但可能这是唯一的方法?嗯,啊,好吧,这看起来非常简洁,但我的初始表达式只得到用户名,而不是整个用户。我没有注意到。很抱歉给您带来不便,但我需要用户对象…更新为仅输出用户对象。您可以使用.Select()进行项目)插入谓词输入允许的任何形式。你说得对,对不起-当你面前没有VS时,很难准确地编写定制代码:)不幸的是,这也不起作用,因为
Gourp.ugLink
是一个“ugLink”列表,而不仅仅是一个“ugLink”…Include()仍然是明确的方向。可能我的代码有误导性,因为我不完全理解您的数据结构。