如何手动以N:N关系加载相关实体?

阿尔瓦罗·加西亚(Alvaro Garcia)

我正在使用EF5,并且当关系为1:N时,如果要加载相关实体,请执行以下操作:

  • 使用T-SQL,我可以使用T-SQL从数据库中加载主要实体,如下所示:

    select * 
    from MainEntities 
    where ...
    
  • 使用T-SQL加载相关实体

    select * 
    from RelatedEntities 
    where IDMainEntity IN (---)
    

此时,EF用相关实体填充主要实体的属性导航。另外,在每个实体的类型的局部属性中,dbContext我具有每种类型的所有实体。

但是,如果我对N:N关系执行相同的操作,则我没有该关系中间表的实体,当我执行查询时,我在dbContext每种类型的实体的本地拥有查询,但是属性导航未填充。

我想知道为什么以及是否存在其他选择。

我之所以使用这种方式,是因为我想使用T-SQL创建动态查询。如果我使用急切加载,则动态查询的灵活性不如使用TSQL的灵活性,而且效率较低。如果我使用显式加载,则我要进行N个附加查询,这是主实体结果中的每条记录之一。按照我的方式,我只会附加一个查询,因为我会立即获得所有相关实体。如果我使用延迟加载,则会遇到相同的问题,即N个其他查询。

当关系为N:N时,为什么EF不填充相关属性?

谢谢。

贫民窟

您正在谈论的功能称为“关系跨度”或“关系修正”,实际上-正如您已经注意到的-它不适用于多对多关系。仅当关联的至少一端具有多重性1(或0..1)时才有效,即,它适用于一对多或一对一关系。

关系跨度依赖于具有外键的实体。它具有显式外键属性(外键关联)还是对应的数据库表中只有外键列而模型中没有属性(独立关联并不重要在这两种情况下,当实体被加载时,FK值都将被加载到上下文中。基于此外键值,EF可以确定是否将与该FK值具有相同主键值的相关实体附加到上下文,如果是,则它可以“修复关系”,即可以填充导航属性正确。

现在,在多对多关系中,两个相关实体都没有外键。外键为此关系存储在链接表中,并且-您知道-链接表没有相应的模型实体。结果,外键将永远不会被加载,因此上下文无法确定关联的附加实体,也无法修复多对多关系并填充导航集合。

EF会支持您以多对多关系使用填充的导航集合构建正确的对象图的唯一LINQ查询急于加载...

var user = context.Users.Include(u => u.Roles).First();

或延迟加载...

var user = context.Users.First();
var rolesCount = user.Roles.Count();
// Calling Count() or any other method on the Roles collection will fill
// user.Roles via lazy loading (if lazy loading is enabled of course)

...或将结果直接分配给导航集合的显式加载:

var user = context.Users.First();
user.Roles = context.Entry(user).Collection(u => u.Roles).Query().ToList();

加载相关实体的所有其他方式(例如投影,直接SQL语句或显式加载而不分配给导航集合),即使用.Load()而不是.Query().ToList()在上面的最后一个代码片段中使用-不会修复该关系,并且会将导航集合留空。

如果您打算主要执行SQL查询而不是LINQ查询,那么我看到的唯一选择是编写自己的关系管理。除了两个相关实体的表之外,您还必须查询链接表。您可能需要一个帮助程序类型(不是实体)和一个包含链接表的两个FK列值的集合,并且可能需要一个帮助程序例程,该例程通过检查您发现的实体的主键值来填充导航集合附加在DbSet<T>.Local集合中以及FK值在助手集合中。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在python中使用numpy for循环手动计算相关系数?

来自分类Dev

如何手动加载 UITableView

来自分类Dev

原则:如何手动设置实体的MySQL时间戳

来自分类Dev

如何分辨依赖关系是手动解决的?

来自分类Dev

手动加载UITextField

来自分类Dev

手动加载位图

来自分类Dev

手动加载UITextField

来自分类Dev

如何手动加载聚合物元件

来自分类Dev

R中的手动皮尔逊相关

来自分类Dev

实体框架多对多关系手动创建第三张表

来自分类Dev

对实体启用手动排序

来自分类Dev

手动同步实体框架

来自分类Dev

手动设置实体的ID

来自分类Dev

如何在ggplot2中手动添加误差线和n =样本大小?

来自分类Dev

当我手动更新行时,Java实体管理器不会加载更改

来自分类Dev

如何手动填充?

来自分类Dev

手动加载框架元素

来自分类Dev

Ubuntu 19.10启动进入GRUB,我必须手动加载内核。如何自动加载?

来自分类Dev

如何避免在实体框架手动插入中重复主键?

来自分类Dev

实体框架-如何手动清除连接池?SNIX_Excecute错误

来自分类Dev

如何查看没有依赖关系手动安装的软件包的列表

来自分类Dev

如何快速加载相关实体

来自分类Dev

EntityFramework无法识别手动进行的实体更改

来自分类Dev

实体框架 6 手动更新记录

来自分类Dev

手动更新 FOs:Elastica 中的实体集合

来自分类Dev

如何通过javascript手动显示标签加载指示器?

来自分类Dev

如何在R中手动创建和加载名称空间

来自分类Dev

如何使用New Relic的页面加载时间数据手动报告?

来自分类Dev

如何在Kendo UI网格中手动加载数据