TPC继承与实体框架的问题

时间:2011-03-11 12:52:44

标签: c# entity-framework

我有2个对象需要分别存储在2个不同的表中。让我们调用类Foo和FooTemp。

我正在使用Table Per Concrete Type(TPC)继承,因为我希望类FooTemp扩展类Foo,我希望数据能够单独存储。

两个表之间的唯一区别是FooTemp有一个额外的字段。

我跟着this guide for setting up TPC inheritance。唯一的区别是我的派生类中有一个额外的字段。

现在,这是我的问题。 当我向数据库添加新记录时,我收到错误:

  

“System.ArgumentException:一个项目   已经有了相同的密钥   添加的“

为什么会出现此错误?有没有其他方法可以在单独的表中进行继承和存储数据?

1 个答案:

答案 0 :(得分:2)

如果您在两个表中定义自动生成的身份密钥,我认为TPC存在问题。虽然从SQL Server的角度来看它不是问题(因为这两个表是分开的,因此可以使用相同的键具有记录)实体框架不允许两个共享相同基类的对象具有相同的键值。但是,如果您在两个表上使用相同种子(例如1)的自动生成密钥,则会发生这种情况。

我不确定这可能是你的问题。如果您从空对象上下文开始,创建新的FooFooTemp,将其添加到上下文并保存更改,则不应出现上述问题。

但例如在以下情况下会发生:

// Imagine, you know that there is a Foo with Key 1 already in the DB, or you
// could also query for that Foo to attach to the context
Foo foo = new Foo() { Key = 1 }; 
context.Foos.Attach(foo);
// Now, we have an object of type Foo with Key 1 in the object context

// Let's assume, that the table FooTemp in the DB is empty. We create the
// first FooTemp
FooTemp fooTemp = new FooTemp();
context.Foos.Add(fooTemp);

context.SaveChanges();
// If the FooTemp table has an autogenerated identity with seed 1 in the DB,
// our FooTemp gets Key 1 in the DB. Because Entity Framework accepts the
// DB changes after calling SaveChanges, our FooTemp object will now have
// the Key 1, so we have a second Foo (since FooTemp derives from Foo) with
// the same Key 1 in the same object context

我可以看到的解决方法:

  • 为两个表格的自动生成的标识定义不同的种子,这两个表格足够远,因此它们不太可能重叠。
  • 关闭自动生成的身份并手动提供密钥。