【发布时间】:2017-06-21 03:53:17
【问题描述】:
使用 C#、.NET 4.5.2、Entity Framework 6.1.3 和 System.Linq 我遇到了一个令人困惑的异常。异常本身似乎不包含确定引发它的原因的有用信息。
以下代码行在执行时会导致 NullReferenceException:
dbCtx.Customers.ToList();
但是,以下行无异常运行并返回正确的结果:
(dbCtx.Customers).ToList();
首先运行括号括起来的表达式将允许两个表单无异常地执行:
var result1 = (dbCtx.Customers).ToList();
var result2 = dbCtx.Customers.ToList();
我还想指出,添加实体按预期工作:
dbCtx.Customers.Add(new Customer() { Enabled = true, Name = "Test" });
客户实体类:
public sealed class Customer : BaseEntity
{
public bool Enabled { get; set; }
[Required]
public string Name { get; set; }
}
BaseEntity 类:
public abstract class BaseEntity
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
}
DbContext 类:
public class MyDbContext : DbContext
{
public MyDbContext() : base(@"Server=.\SQLExpress;Database=MyDatabase;Trusted_Connection=Yes;")
{
Configuration.LazyLoadingEnabled = true;
}
public virtual DbSet<Customer> Customers { get; set; }
}
什么可能导致这种行为?
编辑: 当调用 .ToList()、.Count() 等时,任何实体都会出现此问题。
异常详情:
System.NullReferenceException occurred
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Internal.Linq.InternalSet`1.get_Expression()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Expression()
at MyProjTests.Test1.Test(MyDbContext dbCtx) in E:\ProgrammingProjects\WorkInProgress\MyProjRoot\MyProjTests\Test1.cs:line 51
at MyProjTests.Test1.TestMethod1() in E:\ProgrammingProjects\WorkInProgress\MyProjRoot\MyProjTests\Test1.cs:line 43
编辑 2:
经过实验后,我将其范围缩小为致电dbCtx.Database.CompatibleWithModel(bool)。提供的参数是真还是假没有区别。当我将其注释掉时,代码稍后不会引发 NullReferenceException。我不知道为什么。调用dbCtx.Database.Exists() 工作正常。
此外,dbCtx.Database.Initialize(false); 也可靠地产生错误(不是在调用点,而是在 xyz.ToList())。
【问题讨论】:
-
异常的堆栈跟踪在哪里表明它实际上是被抛出的?无论如何,这似乎很古怪,但这可能会很有趣。另外,如果您不允许延迟加载,问题是否仍然存在?
-
@jmcilhinney 我已经用异常详细信息更新了问题。将延迟加载设置为 false 仍然会产生相同的结果。
-
也许这是因为
Customer是sealed并且 EF 正在尝试创建更改跟踪代理但它失败了?看到这个答案stackoverflow.com/a/5599270/235671 -
@t3chb0t 我之前尝试过,添加或删除
sealed似乎没有任何区别。
标签: c# entity-framework-6 nullreferenceexception