繁体   English   中英

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

[英]Entity Framework 4: Table per Type inheritance problem on insert

我有一个简单的模型,带有“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表中。 为什么不?

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

在此输入图像描述

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

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

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

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

ObjectQuery<Fund> query = container.BaseEntities.OfType<Fund>();

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

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

我已经在VS2010中使用Model-first创建了您的示例,我可以重现您的问题。 问题似乎与模型中的主键不是Int32而是Guid的事实有关。 向模型添加新实体时,设计器始终建议将Int32作为主键, StoreGeneratedPattern设置为Identity

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM