实体框架4:插入时每个类型的表继承问题

时间:2011-02-23 13:41:52

标签: c# entity-framework inheritance entity-framework-4

我有一个简单的模型,带有“BaseEntity”和派生的“Fund”实体。 当我尝试插入新基金时:

HybridModelContainer container = new HybridModelContainer();

//Create new Fund
Fund fund = new Fund();
fund.Id = Guid.NewGuid();
fund.DateCreated = DateTime.Now;
fund.Name = "Fund 1";
fund.Number = 1;
container.BaseEntities.AddObject(fund);

container.SaveChanges();

我收到以下错误:

  

“无法将值NULL插入列'Id',表'HybridData.dbo.BaseEntities';列不允许空值.INSERT失败。
  声明已经终止。“

似乎分配给基金实体的ID未插入BaseEntity表。为什么不?

我做了这个“模特第一”。如果我先设计数据库,并从中创建模型,一切正常......但我需要先建立模型!

enter image description here

另外......为什么我的ObjectSet中没有“FundsDataContext(即container.Funds)?在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:8)

我只能回答你问题的第二部分:“另外......为什么我的DataContext中没有”基金“的ObjectSet(即container.Funds)?”

ObjectContext在类层次结构中只有一个基类的ObjectSet是正常的。实际上并不需要派生类的ObjectSet。要在ObjectContext中添加和删除派生对象,您可以像在示例中一样使用AddObject / DeleteObject的{​​{1}}和ObjectSet<BaseEntity>方法。 / p>

对于查询派生对象,您可以利用ObjectSet的BaseEntities方法。它返回派生类型的ObjectQuery,您可以在其中构建进一步的查询:

OfType

(问题的第一部分听起来像存储和概念模型之间的映射错误。它可能有更好的cif,你可以显示你的edmx文件的相关部分。)

编辑:问题第一部分的可能解决方案:

我已经在VS2010中使用Model-first创建了您的示例,我可以重现您的问题。问题似乎与模型中的主键不是ObjectQuery<Fund> query = container.BaseEntities.OfType<Fund>(); 而是Int32这一事实有关。当您向模型中添加新实体时,设计人员始终建议将Guid作为主键,并将Int32设置为StoreGeneratedPattern

如果您现在将模型设计器中的键类型从Identity更改为Int32,但保持Guid不变为StoreGeneratedPattern,则DDL会创建一个数据库将Identity设置为Id的SQL Server,但该列的标识规范为“否”。

因此,当EF向DB发送INSERT命令时,它会从模型定义中“思考”主数据库将在数据库中自动生成,并且不会将Guid发送到您在代码中分配的数据库。但是DB不会创建密钥,导致密钥为NULL值。因此我们得到的错误。

解决方案:在模型设计器中为uniqueidentifier IdBaseEntity的{​​{1}}属性设置。对我而言,它起作用了。当然,您有责任在向ObjectSet添加新对象之前始终将Guid分配给StoreGeneratedPattern,但这似乎也是您想要的。