【问题标题】:Entity Framework tries setting property to null when querying, after new navigation property is added添加新导航属性后,实体框架在查询时尝试将属性设置为 null
【发布时间】: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 实际上可以使用私有设置器填充类。延迟加载也有效——只要确保构造函数至少受到保护。对于我的领域,我使用构造函数和/或方法来改变对象。
  • 你是对的;我不知道。谢谢(你的)信息。 :)

标签: c# entity-framework


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多