我有两个型号 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<CalculationType> CalculationTypes { get; set; }
public virtual IList<TestEntity> 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<Сalculation> 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; }
}
答案 0 :(得分:4)
试试这个:
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的外键具有该值 具体记录?我这样说是因为价值&#34; null&#34;是有效的 根本没有数据。
P.S。如果您没有在指示器上看到外键,则调用 &#34; IndicatorGroupId&#34;,可能有一个&#34; IndicatorId&#34;在桌子上 &#34; IndicatorGroup&#34;,在这种情况下 - 从您提供的名称 - 您的数据库配置错误,您需要使用流畅的语法 或指示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 :(得分:2)
1)是否启用了延迟加载?如果没有,您需要使用&#39; .Include&#39;明确加载导航属性。语法。
2)你确定EF应该能够检测到这种关系吗?您使用Code First还是Database First?
编辑:3)您确定数据库中是否有数据,并且从Indicator到IndicatorGroup的外键具有该特定记录的值?我这样说是因为价值&#34; null&#34;如果根本没有数据,则有效。
P.S。如果您没有在指示器上看到名为&#34; IndicatorGroupId&#34;的外键,则可能存在&#34; IndicatorId&#34;在表格&#34; IndicatorGroup&#34;,在这种情况下 - 从您提供的名称 - 您的数据库配置错误,您将需要使用流畅的语法或数据属性来指示EF如何制作外键。
答案 2 :(得分:2)
检查出来:Navigation Property With Code First 。它提到了导航属性为空的原因及其解决方案。
默认情况下,导航属性为null,不加载它们 默认。对于加载导航属性,我们使用“include”方法 IQuearable和这种类型的加载称为Eager loading。
预先加载:这是查询一种类型实体的过程 加载相关实体作为查询的一部分,它通过实现 “包括”IQueryable的方法。
答案 3 :(得分:1)
行为相同,但根本原因不同于所选答案:
如果您关闭myContext.Configuration.AutoDetectChangesEnabled
非常明显,但是当我实施一些性能提升时,这就得到了我。
答案 4 :(得分:0)
我遇到了这个问题,即使存在Include
语句,导航属性也没有加载。
此问题是由使用.NET的SQL Server和EF6之间的字符串比较差异引起的。我使用VARCHAR(50)
字段作为customers
表中的主键,也用作audit_issues
表中的外键字段。我没有意识到的是,我在customers
表中的键最后还有两个空格字符。我的audit_issues
表中没有这些字符。
However, SQL Server will automatically pad whitespace for string comparisons。这适用于WHERE和JOIN子句,以及对FOREIGN KEY约束的检查。即数据库告诉我字符串是等效的,并且约束已通过。因此,我假设,它们实际上是完全相同的。但这是错误的。一个字段的DATALENGTH = 10,而另一个字段的DATALENGTH = 8。
EF6将正确地构成SQL查询以提取与外键相关的字段,我将在生成的Sql查询和结果中看到它们。但是,在加载导航属性时, EF6会自动失败,因为.NET不认为这些字符串相等。 当心字符串型外键字段中的空格!。
答案 5 :(得分:-1)
这 article 帮助了我。
总而言之:
Install-Package Microsoft.EntityFrameworkCore.Proxies
在Startup.cs
using Microsoft.EntityFrameworkCore;
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<MyDbContext>(builder =>
{
builder.UseLazyLoadingProxies(); // <-- add this
}, ServiceLifetime.Singleton);