实体框架:为啥对象数组类型的属性没有持久化到数据库?

Posted

技术标签:

【中文标题】实体框架:为啥对象数组类型的属性没有持久化到数据库?【英文标题】:Entity Framework: Why is a property of type array of objects not persisted to DB?实体框架:为什么对象数组类型的属性没有持久化到数据库? 【发布时间】:2014-05-14 05:40:27 【问题描述】:

我有两个实体,其中一个与另一个具有一对多关系。示例:

public class Question

    public int Id  get; set; 
    public string Text  get; set; 
    public Answer[] Answers  get; set; 


public class Answer

    public int Id get; set; 
    public string Text  get; set; 

使用 EF6 Code First 我设置了这个简单的 DbContext:

public class MyContext : DbContext

    public MyContext()
    
        Database.SetInitializer<MyContext>(new DropCreateDatabaseAlways<MyContext>());
    

    public DbSet<Question> Questions  get; set; 

    public DbSet<Answer> Answers  get; set; 

我最终在数据库中得到的是两个结构相似的表(int PK 列和 varchar 列),并且没有表示我打算使用 Question.Answers 属性的“一个问题有很多答案”关系。

为什么 EF Code First 不映射关系,我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

Entity Framework 不支持裸 Array 类型的映射导航属性。该属性必须是实现ICollection&lt;T&gt; 接口的类型才能被映射。

尝试如下更改您的代码:

public class Question

    public int Id  get; set; 
    public string Text  get; set; 
    public virtual ICollection<Answer> Answers  get; set; 

并且在初始化Answers时,将其设置为HashSetList

this.Answers = new List<Answer>();

【讨论】:

谢谢!如果我没有用 ICollection 替换数组的选项怎么办?有什么我可以设置的解决方法吗? 您可以创建一个将由 EF 映射的(私有)支持字段,并通过您当前的 Answer[] Answers 属性公开它。如果您希望我将代码添加到答案中,请告诉我。 非常感谢haim770。请务必将代码添加到答案中以供将来参考。 经过再三考虑,我认为这不是一个好主意,因为您无法从(映射的)答案集合中添加/删除,因为公共 Answers 属性实际上只是一个支持字段的分离副本(使用ToArray() 方法),任何操纵它的尝试都不会被EF跟踪,只会让消费者感到困惑。

以上是关于实体框架:为啥对象数组类型的属性没有持久化到数据库?的主要内容,如果未能解决你的问题,请参考以下文章

实体框架代码第一个值对象持久保存到数据库[重复]

为啥选择实体框架? [关闭]

首先是实体框架代码。如何将对象类型文件的列表添加到已具有该类型属性的对象

JavaWeb_(Hibernate框架)Hibernate中对象的三种状态

java_hibernate 框架2

具有实体框架和空间数据的持久无知域