为什么EF导航属性返回null?
我有两个型号1)
public class Indicator { public long ID { get; set; } public string Name { get; set; } public int MaxPoint { get; set; } public string Comment { get; set; } public DateTime DateChanged { get; set; } public DateTime DateCreated { get; set; } public virtual IList CalculationTypes { get; set; } public virtual IList TestEntitys { get; set; } public virtual IndicatorGroup IndicatorGroup { get; set; } }
2)
public class CalculationType { public long ID { get; set; } public string UnitName { get; set; } public int Point { get; set; } public DateTime DateCreated { get; set; } public DateTime DateChanged { get; set; } public virtual Indicator Indicator { get; set; } public virtual IList Calculations { get; set; } }
我执行这段代码
var indicator = DataContext.Indicators.FirstOrDefault(i => i.ID == indicatorID); var test = DataContext.CalculationTypes.FirstOrDefault();
第一行在导航属性CalculationTypes上返回null
第二行返回空集合。 为什么?
更新快照数据库 项目链接https://github.com/wkololo4ever/Stankin
添加了计算
public class Сalculation { public long ID { get; set; } public virtual CalculationType CalculationType { get; set; } public virtual ApplicationUser Creator { get; set; } }
试试这个:
DbContext.Configuration.ProxyCreationEnabled = true; DbContext.Configuration.LazyLoadingEnabled = true;
如果将DbContext.Configuration.ProxyCreationEnabled设置为false,则除非在父对象上调用Include方法,否则DbContext将不会加载某些父对象的子对象。 将DbContext.Configuration.LazyLoadingEnabled设置为true或false将不会对其行为产生任何影响。
如果DbContext.Configuration.ProxyCreationEnabled设置为true,则将自动加载子对象,并且DbContext.Configuration.LazyLoadingEnabled值将控制何时加载子对象。
我认为这是个问题:
编辑:3)您确定数据库中是否有数据,并且从Indicator到IndicatorGroup的外键具有该特定记录的值? 我这样说是因为如果没有数据,值“null”是有效的。
PS如果你没有在Indicator上看到名为“IndicatorGroupId”的外键,那么“IndicatorGroup”表上可能会有一个“IndicatorId”,在这种情况下 – 从你提供的名字开始 – 你的数据库配置错误,你需要使用流畅的语法或数据属性来指示EF如何制作外键。
尝试这一点,并确保更正外键。
public class CalculationType { public long ID { get; set; } public string UnitName { get; set; } public int Point { get; set; } public DateTime DateCreated { get; set; } public DateTime DateChanged { get; set; } [ForeignKey("IndicatorID")] public string IndicatorId { get; set; } //this is the foreign key, i saw in your database is: Indicator_ID, avoid this, rename it to IndicatorID or IndicatorId public virtual Indicator Indicator { get; set; } public virtual IList<Сalculation> Calculations { get; set; } }
1)是否启用了延迟加载? 如果没有,则需要使用“.Include”语法显式加载导航属性。
2)你确定EF应该能够检测到这种关系吗? 你使用Code First还是Database First?
编辑:3)您确定数据库中是否有数据,并且从Indicator到IndicatorGroup的外键具有该特定记录的值? 我这样说是因为如果没有数据,值“null”是有效的。
PS如果你没有在Indicator上看到名为“IndicatorGroupId”的外键,那么“IndicatorGroup”表上可能会有一个“IndicatorId”,在这种情况下 – 从你提供的名字开始 – 你的数据库配置错误,你需要使用流畅的语法或数据属性来指示EF如何制作外键。
看看这个: 导航属性与代码优先 。 它提到了为什么导航属性为null及其解决方案。
默认情况下,导航属性为null,默认情况下不加载它们。 对于加载导航属性,我们使用IQuearable的“include”方法,这种类型的加载称为Eager加载。
渴望加载:这是一种过程,通过该过程,对一种类型的实体的查询将相关实体作为查询的一部分加载,并且通过IQueryable的“include”方法实现。
相同的行为,但根本原因不同于选定的答案:
如果关闭myContext.Configuration.AutoDetectChangesEnabled
导航属性也可以为null
非常明显,但是当我实施一些性能提升时,这就让我受益匪浅。