鉴于此:
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
);
答案 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表。