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

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(使用前将#替换为@)

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

  • 如何查询多对多表(一个表的值成为列标题)

    给定此表结构 我想展平多对多关系 并将一个表的名称字段中的值设置为列标题 并将同一表中的数量设置为列值 目前可行的想法是将值放入字典 哈希表 中并用代码表示这些数据 但我想知道是否有 SQL 方法可以做到这一点 我还使用 Linq to S
  • MVC3 和实体框架

    我的问题很简单 将 edmxMVC3 项目的 Web 应用程序的模型文件夹中的文件吗 我的答案非常简单 不要用数据访问逻辑和数据建模搞乱表示层 整个 MVC 应用程序 Visual Studio 解决方案中从下到上至少有 4 个项目 1 P
  • 使用 IQueryable 进行单元测试代码

    我被要求为某些功能编写一些单元测试 但坦率地说 我不太确定这样做的必要性或有用性对于这个特殊的一段代码 我绝不试图质疑单元测试的必要性或有用性 所讨论的代码非常简单并且被大量使用 基本上它是 Skip 和 Take 扩展方法的包装 在我看来
  • 使用 DbMigrationsConfiguration 将ExecutionStrategy 设置为 SqlAzureExecutionStrategy?

    我今天看到一篇关于实现 SqlAzureExecutionStrategy 的帖子 http romiller com tag sqlazureexecutionstrategy http romiller com tag sqlazure
  • Dynamic Linq 的执行延迟 IQueryable

    我在用动态链接 https www nuget org packages System Linq Dynamic执行一些查询 抱歉 但这是我唯一的选择 结果 我得到了IQueryable而不是IQueryable
  • 实体框架、dll、excel

    我用C 编写了Excel使用的dll 该dll是COM注册的 我与 Excel 的连接没有问题 该 dll 使用实体框架 5 从 SQL Server 数据库检索数据 如果我通过控制台应用程序运行该 dll 则该 dll 工作正常 但是当我
  • C# 中 LINQ 中的按多列分组

    我有一个类如下 public class ActualClass public string BookName get set public string IssuerName get set public DateTime DateOfI
  • 在实体框架拦截器中向 DbScanExpression 添加内部联接

    我正在尝试使用实体框架 CommandTree 拦截器通过 DbContext 向每个查询添加过滤器 为了简单起见 我有两个表 一个称为 User 有两列 UserId 和 EmailAddress 另一个称为 TenantUser 有两列
  • EF Core 通过完全替换断开集合导航属性的更新

    使用 EF Core 5 0 我有一个 SPA 页面 可以加载Group实体及其集合Employee来自 API 的实体 var groupToUpdate await context Groups Include g gt g Emplo
  • 我的 SQL 表设置为允许该列为 NULL,但是当我运行它时,它说它不能为 NULL。什么/为什么/如何?

    所以我在这里遇到了很奇怪的困境 我的 SQL 表设置为允许 ZipCode 列为空 如下所示 CREATE TABLE dbo Companies CompanyId BIGINT IDENTITY 1 1 NOT NULL PRIMARY
  • 实体框架服务层更新 POCO

    我正在使用Service Layer gt Repository gt Entity Framework Code First w POCO objects方法 我在更新实体方面遇到了困难 我正在使用 AutoMapper 将域对象映射到视
  • 如何使用 linq 查询连接两个不同 edmx 中的两个表

    如何使用 linq 查询连接两个不同 edmx 中的两个表 有没有办法同时从 2 个不同的 edmx 进行查询 Thanks Update 根据您的评论 EF 无法解析跨 2 个不同上下文的组合表达式树 如果表中的记录总数相对较小 或者您可
  • 简单的 Linq 查询对同一个表有重复的连接?

    来自 Julia Lerman 的新实体框架书中的示例 我有一个包含两个表的数据库 联系人和地址 Contact 表有一个 ContactID int 以及名字 姓氏等 Address 表有一个 ContactID 以及城市 州 邮政编码等
  • 运行更新数据库时出错

    我在运行时遇到以下错误Update Database Verbose 使用启动项目 WebApplication 使用 NuGet 项目 Web应用程序 指定 Verbose 标志来查看 SQL 应用于目标数据库的语句 目标数据库是 星冰乐
  • 在同一项目中同时使用 AddDbContextFactory() 和 AddDbContext() 扩展方法

    我正在尝试使用新的DbContextFactory中讨论的模式EF Core 文档的 DbContext 配置部分 https learn microsoft com en us ef core dbcontext configuratio
  • 缺少 EF ObjectContext.SaveChanges

    我正在一个新项目中使用实体框架 我从一年前就开始使用 EF 今天 我尝试使用 Visual Studio 2008 SP1 和 2010 生成实体数据模型 它正在生成对象上下文属性和实体集 但尚未生成 SaveChanges 方法 我什至尝
  • 使用实体框架从 2 个表返回数据

    我正在使用 MVC3 和实体框架 但我需要来自不同表的更多数据 通常我会做这样的事情来从表中获取数据 Table Users id username 在代码中我会做这样的事情来获取所有用户 public static IEnumerable
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp
  • 如何使用自定义 DbFunction 将字符串转换为小数

    我有一个将小数 和其他类型 保存为字符串的表 我想在数据库上下文上编写一个 Linq 查询 该查询将转换为数据库转换而不是本地转换 出于性能原因 This 非工作的example 从概念上讲是我想要实现的目标 using var conte
  • 基本的多对多sql选择查询

    我认为这应该很容易 但它却在逃避我 我的帐户和帐户组之间存在多对多关系 一个帐户可以位于零个或多个组中 因此我使用标准连接表 Accounts ID BankName AcctNumber Balance AccountGroups ID

随机推荐