我哪里错了?我在导航属性NullReferenceExeption
中收到Events
。它被标记为virtual
,并且LazyLoadingEnabled
被明确允许。
程序代码:
using (var db = new Db())
{
var person = new Person();
person.Name = "bla bla";
db.Persons.Add(person);
person.Events = new List<Event>(1);
person.Events.Add(new Event() { Description = "ABC", At = DateTime.Now });
db.SaveChanges();
}
using (var db = new Db())
{
var person = db.Persons.First();
Console.WriteLine(person.Events == null); //Output: True
Console.WriteLine(person.Events.Count); //System.NullReferenceException
}
显式加载:
var person = db.Persons.First();
db.Entry(person).Collection(p => p.Events).Load();
Console.WriteLine(person.Events == null); //Output: False
Console.WriteLine(person.Events.Count); //1
类结构:
class Db : DbContext
{
public Db()
{
Database.SetInitializer(new DropCreateDatabaseAlways<Db>());
Configuration.LazyLoadingEnabled = true;
}
public DbSet<Person> Persons { get; set; }
public DbSet<Event> Events { get; set; }
}
class Person
{
public int id { get; set; }
public string Name { get; set; }
public virtual List<Event> Events { get; set; }
}
class Event
{
public int id { get; set; }
public DateTime At { get; set; }
public string Description { get; set; }
public Person Person { get; set; }
public int PersonId { get; set; }
}
答案 0 :(得分:2)
您的模型类需要公开才能延迟加载。将class Person
和class Event
更改为public class Person
等,您的测试计划将开始有效。
答案 1 :(得分:-1)
很简单。
在Person类和init Events集合中创建默认构造函数,如
public Person()
{
Events = new HashSet<Event>();
}
并将类型为Person的虚拟属性添加到Event类
编辑: 在EF codefirst中,您负责集合初始化,EF负责从数据库中填充此集合
答案 2 :(得分:-1)
将new Person()
替换为context.Persons.Create()
。
这将为您提供实体框架人员代理,而不是Person
。此代理类派生自Person
,但其Events
属性被Lazy加载逻辑覆盖。
然而,这并没有消除代码中的主要问题。哪个是Context的重用。你不应该这样做。
答案 3 :(得分:-1)
您的代码没有任何问题:如果您对空集合执行Count
,您将始终获得NullReferenceException
- 这与Entity Framework无关,那个.NET。
null集合和空集合之间存在差异。
现在,如果您想避免此类NullReferenceException
例外,您始终可以在默认构造函数中启动列表,如:
class Person
{
public Person()
{
Events = new List<Event>();
}
public int id { get; set; }
public string Name { get; set; }
public virtual List<Event> Events { get; set; }
}
答案 4 :(得分:-1)
public class Person
{
public Person()
{
Events = new List<Event>();
}
public int id { get; set; }
public string Name { get; set; }
public virtual List<Event> Events { get; set; }
}
public class Event
{
public int id { get; set; }
public DateTime At { get; set; }
public string Description { get; set; }
public Person Person { get; set; }
public int PersonId { get; set; }
}
您需要使用相同类型的集合和NOT&#39; HashSet#39;来初始化任何Collection导航属性,如下所示。