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

C# 在添加新的导航属性后,实体框架在查询时尝试将属性设置为null,c#,entity-framework,C#,Entity Framework,我在实体框架项目中将导航属性从Customer添加到Purchase(作为集合)。该关系以前已存在,因此不执行数据库迁移 当我从上下文中检索一组非空的产品,该产品还具有指向购买(作为集合)的导航属性时,我得到以下异常: “BrandedProduct”上的“BrandID”属性无法设置为“null”值。必须将此属性设置为“System.Int32”类型的非空值 简化代码(所有实体还具有ID属性和受保护/公共空构造函数): 知道为什么会发生这种情况吗?在本例中,问题似乎是由于BrandedProd

我在实体框架项目中将导航属性从
Customer
添加到
Purchase
(作为集合)。该关系以前已存在,因此不执行数据库迁移

当我从上下文中检索一组非空的
产品
,该产品还具有指向
购买
(作为集合)的导航属性时,我得到以下异常:

“BrandedProduct”上的“BrandID”属性无法设置为“null”值。必须将此属性设置为“System.Int32”类型的非空值

简化代码(所有实体还具有ID属性和受保护/公共空构造函数):


知道为什么会发生这种情况吗?

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


要解决这个问题,只需将
[Key]
属性或另一个
HasKey
添加到带有公共setter的属性的配置中

只是好奇,那些是你的POCO吗?为什么您的ID属性上有一个私有setter?我不完全熟悉POCO的概念,但是这些类形成了一个纯域模型,没有任何实体框架的引用。我使用代码优先迁移,所有实体也都有一个ID。数据库约束是在单独的项目中使用EntityTypeConfiguration定义的,就像我问题中的最后一个代码块一样。私人设置者只是我的一个偏好,这会导致任何问题吗?:)如果您通过这些类检索数据,那么如果setter是私有的,那么如何填充ID呢?实际上,EF可以用私有setter填充类。延迟加载也可以工作——只需确保构造函数至少受到保护。对于我的域,我使用构造函数和/或方法来改变对象;我不知道。谢谢你提供的信息。:)
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...
}
public class DataContext : DbContext {
    protected override void OnModelCreating(DbModelBuilder builder) {
        builder.Entity<Purchase>().HasKey(x => new { x.CustomerID, x.ProductID });
    }
}