我在控制台应用程序中有两个类。
Person
:
class Person {
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Order> Orders { get; set; }
public override string ToString() {
return Id + " " + FirstName + " " + LastName;
}
}
和Order
:
class Order {
//Id to domyslna nazwa na identyfikator -> klucz glowny
public int Id { get; set; }
public int Total { get; set; }
public virtual Person Owner { get; set; }
public override string ToString() {
return Id + " " + Total;
}
}
我的dbContext
是:
class ApplicationDbContext : DbContext {
public DbSet<Person> Persons { get; set; }
public DbSet<Order> Orders { get; set; }
public ApplicationDbContext()
: base("Olek2") {
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public static ApplicationDbContext Create() {
return new ApplicationDbContext();
}
}
我按update-database
生成了新数据库。
在Main
方法中,我尝试获取Person
,然后访问人员订单,但我在p1.Orders.Count()
上获得空指针异常。我将属性设置为虚拟,也启用了延迟加载,我不知道问题出在哪里。
static void Main(string[] args) {
ApplicationDbContext context = new ApplicationDbContext();
Person p1 = context.Persons.Find(1);
Console.WriteLine(p1); // THIS WORKS
Console.WriteLine(context.Orders.Count()); //THIS IS 1
Console.WriteLine(p1.Orders.Count()); //EXCEPTION HERE
Console.ReadKey();
}
也是我的Seed
方法:
protected override void Seed(ApplicationDbContext context) {
Person person = null;
if (!context.Persons.Any()) {
person = new Person() { FirstName = "Alaaaaa", LastName = "Kowlaska" };
context.Persons.AddOrUpdate(person);
}
if (!context.Orders.Any()) {
context.Orders.AddOrUpdate(new Order() { Total = 100, Owner = person });
}
context.SaveChanges();
}
修改
我预感到它与public static ApplicationDbContext Create()
有关,在我的控制台应用程序中有0个引用(VS2013表示)(失败)。
在我的ASP.NET-MVC中(工作正常)它被引用:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
....
}
EDIT2 我有预感,无论如何似乎都没有联系。
答案 0 :(得分:2)
由于您的实体未标记public
修饰符(默认情况下编译器将使它们成为internal
),因此EF将无法为实体类型生成代理。
查看EntityProxyFactory
的{{3}}(第577行):
private static bool CanProxyType(EntityType ospaceEntityType)
{
TypeAttributes access = ospaceEntityType.ClrType.Attributes & TypeAttributes.VisibilityMask;
ConstructorInfo ctor = ospaceEntityType.ClrType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, Type.EmptyTypes, null);
bool accessableCtor = ctor != null && (((ctor.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) ||
((ctor.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family) ||
((ctor.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem));
return (!(ospaceEntityType.Abstract ||
ospaceEntityType.ClrType.IsSealed ||
typeof(IEntityWithRelationships).IsAssignableFrom(ospaceEntityType.ClrType) ||
!accessableCtor) &&
access == TypeAttributes.Public);
}
您可以清楚地注意到CanProxyType
的最后一行,检查实体类型是否确实public
。
现在,既然你没有初始化Person.Orders
(在构造函数中或其他任何地方)并且没有代理涉及拦截对Orders
的调用(初始化它并检测与{的关联) {1}}),最终Order.Person
为空,并抛出NRE。