[英]Entity Framework ObjectQuery.Include()
我有一个对象,其中有两个对象作为属性( User
, PrimaryNode
),都可能为null,请参见下文:
public class Item
{
[Key]
public int ItemId { get; set; }
public string ItemName { get; set; }
public Node PrimaryNode { get; set; }
public User User { get; set; }
}
我正在使用Entity Framework 6填充Item
对象,并使用链式包含在其中填充PrimaryNode
和User
对象。
当第一个链接的Include具有空对象时,则整个对象将返回空值,例如:
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。 以某种方式填充两个子对象的最佳方法是:如果一个子对象为null,则仍将填充父对象和另一个子对象?
我认为如果您在他的情况下使用Lazy loading会更好。 只需将User
和PrimaryNode
虚拟:
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; }
}
然后:
var db = new MyContext();
var item = db.Items.FirstOrDefault(i => i.ItemId == id);
我认为您的问题不是由于Include
通话引起的。 根据文档 :
如果存在这样的方法,则此扩展方法将调用
IQueryable
源对象的Include(String)方法。 如果源IQueryable
没有匹配方法,则此方法不执行任何操作 。
换句话说,将被翻译为:
var item = db.Items.Include("User").Include("PrimaryNode").FirstOrDefault(i => i.ItemId == id);
我的问题是,您确定您有一个ID与数据库中Users
和PrimaryNodes
表中的现有行正确相关的Item
吗? 当您在最后调用Include
方法将转换为联接时,因此,如果关系的FK与该引用的PK不匹配,则查询不应返回期望的结果。
无论如何,如果您想尝试另一个变体来加载相关属性,则可以使用Explicit Loading :
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();
正如其他人所提到的,我认为您的问题并非归因于Includes。 但是,我认为以下方法有价值。 它在功能上等同于您已经对链接的include所做的事情,但是我认为它具有许多好处,包括使用户清楚代码的意图。
包括可以放在扩展方法中:
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);
}
}
}
然后,您可以按以下方式使用扩展名:
using (var db = new MyContext())
{
var itemQuery = db.Items.IncludeUser();
itemQuery = itemQuery.IncludePrimaryNode();
var item = itemQuery.FirstOrDefault(i => i.Id == 1);
}
这只是做同一件事的另一种方式,但是我喜欢它为代码增加的清晰度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.