【问题标题】:How to include all underlying navigation properties automatically with entity framework如何使用实体框架自动包含所有底层导航属性
【发布时间】:2013-05-08 11:48:05
【问题描述】:

场景:我想向数据库中添加一个实体,该实体将具有导航属性,而 实体具有导航属性......等等。基本上数据库中的表是相互连接的——所有的表。

我使用 EF4.3 和上下文/请求模式,所以我不想启用延迟加载;加载我需要的实体只会花费太多时间。到目前为止,我了解到除了像这样使用 include 方法之外别无他法:

 context.Set<TEntity>().include("navproperty1").include("navproperty1.navproperty1.1")... and so on.

这样可维护性会很差,而且代码很多,但是如果我不想手动为每个实体类型编写所有包含,还有其他方法吗?

【问题讨论】:

  • 旁注:navproperty1.navproperty2 也会自动包含 navproperty1。
  • 你确定要那个吗?与延迟加载相比,您最终可能会得到更差的性能和非常复杂的 SQL 查询。更不用说这种查询最终可能通过网络传输的数据量了。但是,它可以作为扩展方法完成,使用实体类型上的反射。
  • 你是先用code吗?
  • nav property1 就我测试而言不会自动加载 nav property2,但可能是我遗漏了一些东西。 @Jure:是的,我知道它的性能真的很差,但是延迟加载对我来说不是一个选择,因为我不希望启用代理,而延迟加载是必需的,对吧?!我试图包含所有导航属性的原因是,“A”实体“与“B”实体有 1:n 关系,但“B”实体与“C”实体有 n:m 关系。如果我不包括“C”到“A”,然后尝试调用 context.SaveChanges(),那么所有数据都会在“B”和“C”之间丢失。知道我该如何解决吗?

标签: c# entity-framework lazy-loading navigation-properties


【解决方案1】:

这里有很多问题。我会尝试解决每一点。

首先,延迟加载并不总是更快。特别是如果您正在加载所有关系。

其次,始终避免使用“魔术字符串”。我不知道接收 lambda 表达式(它是 IQueryable 扩展)的 Include 方法是否可用于 EF 4.3。如果不是,你应该自己实现它like shown here 并使用:

context.Set<TEntity>().include(t => t.NavProp)

“A”实体”与“B”实体有 1:n 关系,但“B”实体有 n:m 与“C”实体的关系。如果我不将“C”包含在“A”中,然后 尝试调用 context.SaveChanges() 那么所有数据都会丢失 “B”和“C”

我真的不明白你的意思。但是,如果您想选择属于列表中某个项目的子导航属性,您应该在 EF 5 中使用它:(不确定它是否适用于 4.3)

context.Set<TEntity>().Include(t => t.Collection.Select(c => c.SubProp))

其他表达可以找here

如果你澄清那句话,也许我可以提供更多帮助。

【讨论】:

  • 包含字符串实际上非常方便,尤其是在您实现 JSON-API 时
  • 非常有用,谢谢。此外,要添加到您的答案中 - 要在 .Include() 方法中使用 lambda 表达式,您需要确保您是 using System.Data.Entity,正如我发现的那样。另一种避免魔术字符串的方法是使用nameof(Entity.Property),也
【解决方案2】:

看看这个sn-p

var dbQuery =
context.Letters.Where(letter => letter.ID == myId)
   .Include(l => l.Recipients.Select(y => y.PersonTitle))//this will include letter.Recipients.PersonTitle
   .Include(l => l.PersonTitle)
   .Include(l => l.Rank)
   .Include(l => l.JobTitle);
theLetter = dbQuery.FirstOrDefault();// maybe null returned

这一行

context.Letters.Include(l => l.Recipients.Select(y => y.PersonTitle))

将收到带有Recipients 的字母,您可以访问存在于收件人导航属性中的PersonTitle

这意味着 导航属性 withen 导航属性

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 2011-05-26
    相关资源
    最近更新 更多