实体框架 - 预加载两个多对多关系

2024-01-31

很抱歉这么长,但至少我认为我获得了所有信息以便能够理解并可能有所帮助?

我想使用预加载从数据库加载数据。

数据设置在五个表中,设置两个级别的 m:n 关系。因此,存在三个包含数据的表(以从上到下的层次结构方式排序):

CREATE TABLE [dbo].[relations](
    [relation_id] [bigint] NOT NULL
)

CREATE TABLE [dbo].[ways](
    [way_id] [bigint] NOT NULL
)

CREATE TABLE [dbo].[nodes](
    [node_id] [bigint] NOT NULL,
    [latitude] [int] NOT NULL,
    [longitude] [int] NOT NULL
)

前两个实际上只包含它们自己的 ID(用于挂钩此处不相关的其他数据)。

在这三个数据表之间是两个 m:n 表,带有排序提示:

CREATE TABLE [dbo].[relations_ways](
    [relation_id] [bigint] NOT NULL,
    [way_id] [bigint] NOT NULL,
    [sequence_id] [smallint] NOT NULL
)

CREATE TABLE [dbo].[ways_nodes](
    [way_id] [bigint] NOT NULL,
    [node_id] [bigint] NOT NULL,
    [sequence_id] [smallint] NOT NULL
)

这本质上是 OpenStreetMap 数据结构的一部分。我让实体框架从该数据库构建它的对象,并按照表的形式设置类。 m:n 表确实作为类存在。 (我知道在 EF 中,您可以构建对象 m:n 关系,而无需明确的中间类 - 我应该尝试以这种方式更改对象模型吗?)




我想做的事:我的切入点正是一项关系。

我认为最好首先急切加载中间的 m:n 关系,然后在循环中迭代该关系并急切加载最低的关系。我尝试通过以下方式做到这一点

IQueryable<relation> query = context.relations;
query = query.Where( ... ); // filters down to exactly one
query = query.Include(r => r.relation_members);
relation rel = query.SingleOrDefault();

只需一次访问数据库即可加载关系以及所有 1:n 信息 - 好吧,很好。但我注意到它只加载 1:n 表,而不加载中间数据表“ways”。

如果我像这样修改该行,这不会改变:

query = query.Include(r => r.relation_members.Select(rm => rm.way));

所以我似乎无法在这里加载中间级别?

我根本无法工作的是急切地加载节点级别的数据。我尝试了以下方法:

foreach (relation_member rm in rel.relation_members) {
    IQueryable<way_node> query = rm.way.way_nodes.AsQueryable();
    query = query.Include(wn => wn.node);
    query.Load();
}

这确实有效,并且在每次迭代的一个语句中急切地加载中间级别的方式和 way_node 的所有 1:n 信息,但是not来自节点的信息(纬度/经度)。如果我访问这些值之一,我会触发另一次数据库访问以加载一个单节点对象。

最后一次旅行是致命的,因为我想加载 1 个关系 -> 300 个路径,每个路径 -> 2000 个节点。所以最终我会选择服务器 1 + 300 + 300*2000...我认为还有改进的空间。

但如何呢?我无法用有效的语法和急切加载来编写最后一条语句。 不感兴趣;有没有一种方法可以从一个关系开始一次加载整个对象图?


在一次往返中加载整个图表将是:

IQueryable<relation> query = context.relations;
query = query.Where( ... ); // filters down to exactly one
query = query.Include(r => r.relation_members
    .Select(rm => rm.way.way_nodes
        .Select(wn => wn.node)));
relation rel = query.SingleOrDefault();

不过,既然你这么说Include up to ...Select(rm => rm.way)没有起作用,这不太可能起作用。 (如果它能工作,由于生成的 SQL 的复杂性以及该查询将返回的数据和实体的数量,性能可能并不好笑。)

您应该进一步调查的第一件事是为什么.Include(r => r.relation_members.Select(rm => rm.way))不起作用,因为它看起来是正确的。您的模型和到数据库的映射正确吗?

通过显式加载获取节点的循环应如下所示:

foreach (relation_member rm in rel.relation_members) {
    context.Entry(rm).Reference(r => r.way).Query()
        .Include(w => w.way_nodes.Select(wn => wn.node))
        .Load();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架 - 预加载两个多对多关系 的相关文章

  • EF4 Code First:如何在不添加导航属性的情况下添加关系

    我应该如何使用 Code First 但不使用任何导航属性来定义关系 之前 我通过在关系的两端使用导航属性来定义一对多和多对多 并在数据库中创建适当的关系 这是类的精简版本 为了简单起见 我已将多对多关系转换为一对多关系 public cl
  • Entity Framework Code First 是否允许在单独的文件中进行流畅的映射?

    我正在使用实体框架代码优先开发一个相当大的数据库模式 与数据注释方法相比 我更喜欢 Fluent API 因为它将我的域对象保留为简单的 POCO 为了使用 Fluent API 我必须在继承自 DbContext 的类中重写 OnMode
  • 我可以删除单个子实体而不加载整个集合吗?

    我有 2 个课程 如下所示 它们可以拥有非常大的集合 一个网站可能有 2 000 多个网站页面 反之亦然 class WebsitePage public int ID get set public string Title get set
  • 静态构造函数中的 Database.SetInitializer() ?

    许多人可能知道为什么我们需要使用下面所示的代码 但是 我想将此逻辑分成几层 并且不想在 Web 层中引用实体框架 DLL 因此我最终将此代码放入我的静态构造函数中DbContext class 这是一个坏主意吗 这样做会对应用程序的性能造成
  • 我可以将 UseCSharpNullComparisonBehavior 用于单个查询吗?

    我有一个查询 该查询曾经是存储过程 现已转换为 EF 查询 现在已经超时了 使用 SQL Profiler 我可以看到生成的 SQL 的唯一区别是 EF 转变的新行为entity Property value into entity Pro
  • 传递选择器函数时,OrderBy 不会转换为 SQL

    当我执行时 var t db Table1 OrderBy x gt x Name ToList 在 SQL 分析器中 这是翻译后的 SQL SELECT Extent1 ID AS ID Extent1 Name AS Name FROM
  • 有没有办法将所有内容都包含在 dbcontext 中?

    当查询一个DbContext急切加载时 需要Include Navigation 为了填充导航属性 然而 在某些情况下 我想简单地Include all实体的导航属性 有没有办法做到这一点 或者有办法做到这一点 我假设你可以反思 但我宁愿避
  • 如何修改 edmx 的默认代码生成策略?

    我想修改默认的代码生成策略 该怎么做 我只是想修改类名 lt code Escape container gt to Entities并将默认连接字符串更改为name Default 我不想为该项目创建模板文件 我想编辑它以便它可以在全球范
  • LINQ to Entities 如何更新记录

    好的 我对 EF 和 LINQ 都是新手 我已经弄清楚如何插入和删除 但由于某种原因更新似乎逃脱了我的掌握 这是我的代码示例 EntityDB dataBase new EntityDB Customer c new Customer Na
  • 如何通过实体键添加/删除与实体框架的多对多关系?

    I tried using Entities e new Entities EntityKey key new EntityKey Entities Users UserId 20 User user new User EntityKey
  • 如何在 MVC5 中创建两种类型的用户?

    我正在创建 MVC5 应用程序 并且已经在使用 ASP NET Identity 来创建用户 因此 我已经有了 AspNetUsers 表 每当用户注册时 我都会在那里获得一个条目 我还有一个管理员角色 我可以手动指定哪个注册用户是管理员
  • 如何使用 linq to sql 一次更新多行?

    Table id userid friendid name status 1 1 2 venkat false 2 1 3 sai true 3 1 4 arun false 4 1 5 arjun false 如果用户发送userid 1
  • 在运行时更改实体框架数据库架构

    在大多数 ASP NET 应用程序中 您可以通过在运行时修改连接字符串来更改数据库存储 即 我可以通过简单地更改连接字符串中 数据库 字段的值来从使用测试数据库更改为生产数据库 我正在尝试使用实体框架更改架构 但不一定是数据库本身 但没有成
  • 使用 Entity Framework Core 2.0 更改或重命名列名称而不丢失数据

    我意识到我的一个列标题拼写错误 因此我在模型中更改了它并创建了一个新的迁移以将其更新到数据库中 一切都很完美 直到我意识到实际发生的情况是一个新列取代了现有列并删除了所有数据 碰巧的是 由于这是一个教程数据库 因此恢复数据并不重要 只需几分
  • 识别关系并插入子实体会导致“无法在表中插入标识列的显式值”

    我正在尝试在实体框架中获取可识别的关系 以便我可以使用 删除 从其集合中删除项目 我创建了一个测试 例如 public class OrderLine Key Column Order 0 public int OrderLineId ge
  • 实体框架连接字符串定义

    我只是想知道 什么是实体框架连接字符串实际意思 喜欢 metadata res Models Model1 csdl res Models Model1 ssdl res Models Model1 msl provider System
  • 从 SQLCE 4 迁移到 SQL Server 2008

    因此 作为早期采用者 我开发了一个基于 SQLCE4 ASP Net MVC3 和实体框架CTP5 http www microsoft com downloads en details aspx FamilyID 35adb688 f8a
  • 如何使用 EF Code First 解释枚举类型

    这是一个模型 Public class Person Key Public int PersonId get set Public int Age get set Public ColorEnum FavoriteColor get set
  • EF 5.0 枚举未生成

    背景我在安装了 Net 4 5 的机器上使用 VS 2010 我读到这是就地安装 覆盖了 net 4 0 版本 我的项目仍然针对 4 0 而 4 5 选项不可用 但被告知没关系 因为 4 5 是就地安装 然后 我通过 nuget 安装了 E
  • MVC3数据缓存技术

    我有一个 sql 查询 存储过程 在结果显示在网络网格中之前需要大约 8 10 秒才能返回 关于 asp net mvc3 中的缓存的性能最佳实践是什么 以便用户不必每次都花费 8 10 秒来加载该数据 减少优化查询 你可以使用内存缓存 h

随机推荐