首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架ObjectQuery.Include()

实体框架ObjectQuery.Include()
EN

Stack Overflow用户
提问于 2016-01-06 18:21:22
回答 3查看 1.1K关注 0票数 6

我有一个具有两个对象作为属性的对象(UserPrimaryNode),这两个对象都可能为null,请参见下面的内容:

代码语言:javascript
复制
public class Item
{
    [Key]
    public int ItemId { get; set; }
    public string ItemName { get; set; }
    public Node PrimaryNode { get; set; }
    public User User { get; set; }
}

我使用EntityFramework6填充Item对象,并使用链式包含来填充其中的PrimaryNodeUser对象。

当第一个链式包含有一个空对象时,整个对象返回为null,例如:

代码语言:javascript
复制
using (var db = new MyContext())
{
    var item = db.Items.Include(i => i.User).Include(n => n.PrimaryNode).FirstOrDefault(i => i.ItemId == id);
}

如果在上面的示例中,i.User为null,那么item变量为null。如果子对象为空,那么父对象和其他子对象仍将被填充,那么填充两个子对象的最佳方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-06 18:46:55

我不认为你的问题是由于Include的电话。符合文档

如果存在此扩展方法,则该扩展方法将调用包括(字符串)源对象的IQueryable方法。如果源IQueryable没有匹配方法,则此方法不执行任何操作。

换言之,将翻译为:

代码语言:javascript
复制
 var item = db.Items.Include("User").Include("PrimaryNode").FirstOrDefault(i => i.ItemId == id);

我的问题是,您确定您有一个id与数据库中的ItemPrimaryNodes表中的现有行正确关联的PrimaryNodes吗?当您在末尾调用Include方法时,将被转换为一个连接,因此,如果您关系的FK与该引用的PK不匹配,则您的查询不应该返回您所期望的内容。

无论如何,如果您想尝试另一个变量来加载相关属性,则可以使用显式加载

代码语言:javascript
复制
var item = db.Items.FirstOrDefault(i => i.ItemId == id);
context.Entry(item).Reference(p => p.PrimaryNode).Load(); 
context.Entry(item).Reference(p => p.User).Load();
票数 1
EN

Stack Overflow用户

发布于 2016-01-06 18:29:13

我认为如果你在他的情况下使用延迟加载会更好。只需将UserPrimaryNode变为虚拟:

代码语言:javascript
复制
public class Item
{
   [Key]
   public int ItemId { get; set; }
   public string ItemName { get; set; }
   public virtual Node PrimaryNode { get; set; }
   public virtual User User { get; set; }
}

然后:

代码语言:javascript
复制
var db = new MyContext();
var item = db.Items.FirstOrDefault(i => i.ItemId == id);
票数 1
EN

Stack Overflow用户

发布于 2016-01-06 19:10:38

正如其他人所提到的,我认为你的问题并不是因为包括在内。但是,我认为下面的方法有价值。它在功能上相当于您已经对链式包含所做的工作,但我认为它有几个好处,包括使代码的意图向用户明确。

可以将包含放在扩展方法中:

代码语言:javascript
复制
using System.Data.Entity;
using System.Linq;

namespace Stackoverflow
{
    public static class EntityExtensions
    {
        public static IQueryable<Item> IncludePrimaryNode(this IQueryable<Item> query)
        {
            // eager loading if this extension method is used
            return query.Include(item => item.PrimaryNode);
        }

        public static IQueryable<Item> IncludeUser(this IQueryable<Item> query)
        {
            // eager loading if this extension method is used
            return query.Include(item => item.User);
        }
    }
}

然后,您可以按以下方式使用扩展:

代码语言:javascript
复制
using (var db = new MyContext())
{
    var itemQuery = db.Items.IncludeUser();

    itemQuery = itemQuery.IncludePrimaryNode();

    var item = itemQuery.FirstOrDefault(i => i.Id == 1);
}

这只是做同样事情的另一种方式,但我喜欢它为代码增加的清晰性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34640034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档