添加新导航属性后,实体框架在查询时尝试将属性设置为 null

Posted

技术标签:

【中文标题】添加新导航属性后,实体框架在查询时尝试将属性设置为 null【英文标题】:Entity Framework tries setting property to null when querying, after new navigation property is added 【发布时间】:2016-04-22 10:33:45 【问题描述】:

我在我的实体框架项目中添加了一个从CustomerPurchase 的导航属性(作为一个集合)。该关系之前已经存在,因此不会执行数据库迁移。

当我从上下文中检索一组非空的 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 实际上可以使用私有设置器填充类。延迟加载也有效——只要确保构造函数至少受到保护。对于我的领域,我使用构造函数和/或方法来改变对象。 你是对的;我不知道。谢谢(你的)信息。 :) 【参考方案1】:

在此示例中,问题似乎是由于 BrandedProduct 没有实体框架所需的主键。它试图找出并设置BrandID 作为主键,它有一个私有的setter。

要解决这个问题,只需将[Key] 属性或另一个HasKey 添加到您的配置中,以获得具有公共设置器的属性。

【讨论】:

以上是关于添加新导航属性后,实体框架在查询时尝试将属性设置为 null的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 6:将子对象添加到父列表与将子对象的导航属性设置为父对象

实体框架对导航属性的约束

cass怎么给实体添加属性

实体框架上的急切加载导航属性

实体框架代码优先导航问题

实体框架Linq查询:如何在多个导航属性上从何处选择并从第三个导航属性中选择