简体   繁体   English

TPC继承与实体框架的问题

[英]Issues with TPC inheritance with entity framework

I have 2 objects that I want stored separately in 2 different tables. 我有2个对象,我想分别存储在2个不同的表中。 Let's call the classes Foo and FooTemp. 让我们调用类Foo和FooTemp。

I'm using Table Per Concrete Type (TPC) inheritance since I want class FooTemp to extend class Foo and I want the data to be stored separately. 我正在使用Table Per Concrete Type(TPC)继承,因为我希望类FooTemp扩展类Foo并且我希望数据分开存储。

The only difference between the 2 tables is FooTemp has an extra field. 两个表之间的唯一区别是FooTemp有一个额外的字段。

I followed this guide for setting up TPC inheritance . 我按照本指南设置了TPC继承 The only difference is that I have a extra field in my derived class. 唯一的区别是我的派生类中有一个额外的字段。

Now, here is my problem. 现在,这是我的问题。 When I add a new record to the database I get the error: 当我向数据库添加新记录时,我收到错误:

"System.ArgumentException: An item with the same key has already been added" “System.ArgumentException:已添加具有相同键的项目”

Why do I get this error? 为什么我会收到此错误? Is there any other way of doing inheritance and storing data in separate tables? 有没有其他方法可以在单独的表中进行继承和存储数据?

I believe there is a problem with TPC if you are defining autogenerated identity keys in both of your tables. 如果您在两个表中定义自动生成的身份密钥,我相信TPC存在问题。 Although from SQL Server perspective it isn't an issue (since the two tables are separate and can therefore have records with the same key) Entity Framework doesn't allow two objects which share the same base class to have the same key value. 虽然从SQL Server的角度来看它不是问题(因为这两个表是分开的,因此可以使用相同的键具有记录)实体框架不允许两个共享相同基类的对象具有相同的键值。 But this can happen if you have autogenerated keys on both tables with the same seed (for instance 1) of the identity. 但是,如果您在两个表上使用相同种子(例如1)的自动生成密钥,则会发生这种情况。

I am not sure if that could be your problem. 我不确定这可能是你的问题。 The problem I described above should not occur if you start with an empty object context, create a new Foo or FooTemp , add it to the context and save the changes. 如果您从空对象上下文开始,创建新的FooFooTemp ,将其添加到上下文并保存更改,则不应出现上述问题。

But it would occur for instance in the following situation: 但它会发生在例如以下情况:

// 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

Workarounds I can see: 我可以看到的解决方法:

  • Define different seeds for the autogenerated identites for the two tables which are distant enough so that it's unlikely that they ever will overlap. 为两个表格的自动生成的标识定义不同的种子,这两个表格足够远,因此它们不太可能重叠。
  • Switch off autogenerated identites and supply your keys manually. 关闭自动生成的身份并手动提供密钥。

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

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