我有一个由以下类组成的多级继承heriarchy:
public abstract class BasePoco
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
}
public class Activity : BasePoco
{
public ActivityType ActivityType { get; set; }
[MaxLength(1000)]
public string Description { get; set; }
}
现在有一种特殊类型的Activity称为数据捕获活动。 有两种类型:DataCaptureActivity和MasterDataCaptureActivity
public class DataCaptureActivityBase : Activity
{
[MaxLength(100)]
public string Title { get; set; }
}
派生类:
[Table("DataCaptureActivities")]
public class DataCaptureActivity : DataCaptureActivityBase
{
public virtual DataCaptureActivityType DataCaptureActivityType { get; set; }
}
[Table("MasterDataCaptureActivities")]
public class MasterDataCaptureActivity : DataCaptureActivityBase
{
public virtual string SomeOtherField{ get; set; }
}
问题出在创建迁移时,应该属于Title
的列DataCaptureActivity
实际上是Activity
表的一部分。
请注意,DataCaptureActivityBase
不应该是我的架构中的表。它仅用于保存公共参数DataCaptureActivities
表及其继承类型。
我定位的架构是:
Activity
-------------------------------
Id | ActivityType | Description
DataCaptureActivity
--------------------------------
Id | Title
MasterDataCaptureActivity
--------------------------------
Id | Title | SomeOtherField
答案 0 :(得分:1)
您的上下文与此类似
public DbSet<Activity> Activity { get; set; }
public DbSet<DataCaptureActivity> DataCaptureActivities { get; set; }
public DbSet<MasterDataCaptureActivity> MasterDataCaptureActivities { get; set; }
您在概念上对EF说的是DataCaptureActivity
是Activity
而MasterDataCaptureActivity
是Activity
。在数据库上,您将创建所有三个实体
使用此模型,语句
context.Activities.ToList();
检索所有Activities
(三组联合)。
要对您的模型执行此操作,数据库上的EF将使用Discriminator创建Activity表。表结构将是这样(看1-1关系):
ExecuteNonQuery==========
CREATE TABLE [Activity] (
[Id] int not null identity(1,1)
, [ActivityType] int not null
, [Description] text null
, [Title] varchar(100) null
, [Discriminator] varchar(128) not null
);
ALTER TABLE [Activity] ADD CONSTRAINT [PK_Activity_7ea65be8] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [DataCaptureActivities] (
[Id] int not null
, [DataCaptureActivityType] int not null
);
ALTER TABLE [DataCaptureActivities] ADD CONSTRAINT [PK_DataCaptureActivities_7ea65be8] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [MasterDataCaptureActivities] (
[Id] int not null
, [SomeOtherField] text null
);
ALTER TABLE [MasterDataCaptureActivities] ADD CONSTRAINT [PK_MasterDataCaptureActivities_7ea65be8] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE INDEX [IX_Id] ON [DataCaptureActivities] ([Id])
ExecuteNonQuery==========
CREATE INDEX [IX_Id] ON [MasterDataCaptureActivities] ([Id])
ExecuteNonQuery==========
ALTER TABLE [DataCaptureActivities] ADD CONSTRAINT [FK_DataCaptureActivities_Activity_Id] FOREIGN KEY ([Id]) REFERENCES [Activity] ([Id])
ExecuteNonQuery==========
ALTER TABLE [MasterDataCaptureActivities] ADD CONSTRAINT [FK_MasterDataCaptureActivities_Activity_Id] FOREIGN KEY ([Id]) REFERENCES [Activity] ([Id])
此外,这句话
using (var context = new Context(GetConnection()))
{
context.DataCaptureActivities.Add(new DataCaptureActivity() {Description = "Description"});
context.SaveChanges();
}
将生成此DML语句(2个插入语句!!!)
ExecuteDbDataReader==========
insert into [Activity]([ActivityType], [Description], [Title], [Discriminator])
values (@p0, @p1, null, @p2);
select [Id]
from [Activity]
where [Id] = @@identity
@p0 = 0
@p1 = Description
@p2 = DataCaptureActivity
ExecuteNonQuery==========
insert into [DataCaptureActivities]([Id], [DataCaptureActivityType])
values (@p0, @p1);
@p0 = 1
@p1 = 0
定位表格的解决方案
您需要更改模型,说明DataCaptureActivities和MasterDataCaptureActivities不是活动。
例如:
public abstract class BasePoco
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
}
public class BaseActivity : BasePoco
{
public ActivityType ActivityType { get; set; }
[MaxLength(1000)]
public string Description { get; set; }
}
[Table("Activity")]
public class Activity : BaseActivity
{
}
public class DataCaptureActivityBase : BaseActivity
{
[MaxLength(100)]
public string Title { get; set; }
}
[Table("DataCaptureActivities")]
public class DataCaptureActivity : DataCaptureActivityBase
{
public virtual DataCaptureActivityType DataCaptureActivityType { get; set; }
}
[Table("MasterDataCaptureActivities")]
public class MasterDataCaptureActivity : DataCaptureActivityBase
{
public virtual string SomeOtherField { get; set; }
}
在这种情况下,表结构将是这个
ExecuteNonQuery==========
CREATE TABLE [Activity] (
[Id] int not null identity(1,1)
, [ActivityType] int not null
, [Description] text null
);
ALTER TABLE [Activity] ADD CONSTRAINT [PK_Activity_2b28bd47] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [DataCaptureActivities] (
[Id] int not null identity(1,1)
, [DataCaptureActivityType] int not null
, [Title] varchar(100) null
, [ActivityType] int not null
, [Description] text null
);
ALTER TABLE [DataCaptureActivities] ADD CONSTRAINT [PK_DataCaptureActivities_2b28bd47] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [MasterDataCaptureActivities] (
[Id] int not null identity(1,1)
, [SomeOtherField] text null
, [Title] varchar(100) null
, [ActivityType] int not null
, [Description] text null
);
ALTER TABLE [MasterDataCaptureActivities] ADD CONSTRAINT [PK_MasterDataCaptureActivities_2b28bd47] PRIMARY KEY ([Id])
但在这种情况下,如果您想要在客户端上枚举所有ActivityBase
您需要加入它们(Union
)。
答案 1 :(得分:0)
尝试执行以下步骤。
abstract
MapInheritedProperties();
希望这有帮助