【发布时间】:2016-04-22 10:33:45
【问题描述】:
我在我的实体框架项目中添加了一个从Customer 到Purchase 的导航属性(作为一个集合)。该关系之前已经存在,因此不会执行数据库迁移。
当我从上下文中检索一组非空的 Product - 它还具有指向 Purchase 的导航属性(作为集合)时,我得到以下异常:
“BrandedProduct”上的“BrandID”属性无法设置为“null”值。您必须将此属性设置为“System.Int32”类型的非空值。
简化代码(所有实体也有一个 ID 属性和一个受保护/公共的空构造函数):
public class Customer {
// Adding this line causes the exception. Without it, everything works fine.
public virtual ICollection<Purchase> Purchases { get; private set; }
}
public abstract class Product {
public virtual ICollection<Purchase> Purchases { get; private set; }
}
public class BrandedProduct : Product {
// This is the property that EF tries to set to null
public int BrandID { get; private set; }
public virtual Brand Brand { get; private set; }
}
public class Brand {}
// This works as a many-to-many relationship between Product and Customer
public class Purchase {
public int CustomerID { get; private set; }
public int ProductID { get; private set; }
public virtual Customer Customer { get; private set; }
public virtual Product Product { get; private set; }
// Other properties...
}
Purchase类有复合主键,所以在DataContext类中设置如下配置。
public class DataContext : DbContext {
protected override void OnModelCreating(DbModelBuilder builder) {
builder.Entity<Purchase>().HasKey(x => new { x.CustomerID, x.ProductID });
}
}
知道为什么会发生这种情况吗?
【问题讨论】:
-
只是好奇,这些是你的 POCO 吗?为什么你的 ID 属性上有一个私有的 setter?
-
我对 POCO 的概念并不完全熟悉,但是这些类形成了一个纯领域模型,没有任何实体框架的引用。我使用代码优先迁移,所有实体也都有一个 ID。数据库约束是使用EntityTypeConfigurations定义的,就像我问题中的最后一个代码块一样,在一个单独的项目中。私人二传手只是我的偏好,这会导致任何问题吗? :)
-
如果您通过这些类检索数据,如果 setter 是私有的,将如何填充 ID?
-
嗯,EF 实际上可以使用私有设置器填充类。延迟加载也有效——只要确保构造函数至少受到保护。对于我的领域,我使用构造函数和/或方法来改变对象。
-
你是对的;我不知道。谢谢(你的)信息。 :)
标签: c# entity-framework