EF 4.1 Code First。每个类型的表继承,具有与其基类的主键名不同的主键名

时间:2011-09-02 03:39:00

标签: entity-framework inheritance entity-framework-4.1

鉴于此:

create table Location(
LocationId int identity(1,1) not null primary key,
Address nvarchar(max) not null,
City nvarchar(max) null,
State nvarchar(max) not null,
ZipCode nvarchar(max) not null
);



create table Park(
ParkId int not null primary key references Location(LocationId),
Name nvarchar(max) not null
);

我尝试了这种映射:

modelBuilder.Entity<Location>();
modelBuilder.Entity<Park>().ToTable("Park");
modelBuilder.Entity<Park>().Property(x => x.LocationId).HasColumnName("ParkId");

不幸的是,这不起作用。

using (var db = new Ef())
{
    var park = new Park { Name = "11th Street Park", Address = "801 11th Street", City = "Aledo", State = "TX", ZipCode = "76106" };
    db.Set<Location>().Add(park);

    db.SaveChanges();
}

出现此错误:

  

属性'LocationId'不是'Park'类型的声明属性。   验证是否未明确排除该属性   使用Ignore方法或NotMappedAttribute数据建模   注解。确保它是有效的原始属性。

我应该如何映射Park实体,使其LocationId属性降为ParkId列?

我顺便说一下这个映射:

public class Location
{
    public virtual int LocationId { get; set; }
    public virtual string Address { get; set; }
    public virtual string City { get; set; }
    public virtual string State { get; set; }
    public virtual string ZipCode { get; set; }
}

public class Park : Location
{
    public virtual string Name { get; set; }
}

如果它可以提供帮助,这可以在EF 4.0(通过设计人员)中实现,只需遵循实体框架4.0配方,问题解决方案方法的第2-11章中的步骤。现在我首先通过EF 4.1

尝试代码

[编辑]

如果我将ParkId更改为LocationId,一切正常。但是,通过设计器方法,可以将LocationId映射到表Park的ParkId;我想先用代码实现同样的目标

create table Park( 
LocationId int not null primary key references Location(LocationId), 
Name nvarchar(max) not null 
); 

2 个答案:

答案 0 :(得分:3)

据我所知(我多次尝试过)代码首先不支持这个=&gt;您的派生类型应使用相同的主键名列。

这个问题可以非常简单地描述:当前流畅的映射实现不允许从父实体覆盖映射规则=&gt;父实体定义所有派生实体中主键列的名称。

IMO最可能的原因是它实际上是作为代码设计的,你没有现有的数据库而且你不必费心数据库命名 - EF需要根据需要定义名称。一旦发布了DbContext API,人们开始大量使用现有数据库。但是这里出现了一个问题:初始用例没有计算在内,所以在EDMX中很容易完成的一些场景是不可能的。这是其中之一。

答案 1 :(得分:0)

以下是此问题的解决方法:

为派生表创建一个视图,并将您的实体类映射到该视图。重命名视图中的键列,使其与基表中的键列匹配。

例如:

基表用户(UserID,FirstName,LastName)

派生表管理器(ManagerID,DepartmentID)

实体框架无法更新管理器,因为键列不同!

溶液:

create view UserManager
as
select
ManagerID as UserID,
DepartmentID
from Manager

然后将Manager类映射到UserManager视图,而不是映射到Manager表。