实体框架 4.1 代码优先映射到将主键作为外键列的表

Posted

技术标签:

【中文标题】实体框架 4.1 代码优先映射到将主键作为外键列的表【英文标题】:Entity Framework 4.1 Code first mapping to tables that have their primary key as the foreign key column 【发布时间】:2012-02-15 19:44:29 【问题描述】:

我有一个现有的数据库,我使用 Entity Framework Code First 进行映射。列的命名约定很奇怪,所以我决定手动映射实体属性,到目前为止这还不错。

数据库的架构对我来说相当陌生,而且绝对不是我会这样做的。不幸的是,我暂时坚持了下来。

基本上,多个表共享一个主键(AccountNumber),创建一堆一对一的关系。但是,主键也是外键列。这是我的实体的样子(为简单起见,删除了一大堆属性)。为了方便起见,我只包含了两个实体。:

public class Customer

    public int AccountNumber  get; set; 
    public String PhoneNumber  get; set; 
    ...
    public virtual Address Address  get; set; 


public class Address

    public int AccountNumber  get; set; 
    public String Name  get; set; 
    public String Address1  get; set; 
    public String City  get; set; 
    ...
    public virtual Customer Customer  get; set; 

这两个实体共享相同的主键。我创建了配置类来进行这样的映射:

public class CustomerConfiguration : EntityTypeConfiguration<Customer>

    public CustomerConfiguration()
        : base()
    
        HasKey(p => p.AccountNumber);
        Property(p => p.AccountNumber).
            HasColumnName("cm_l_acct").
            IsRequired();
        Property(p => p.PhoneNumber).
            HasColumnName("cm_s_phonenumber");

        HasRequired(x => x.Address).
            WithRequiredPrincipal(x => x.Customer).
            Map(x => x.MapKey("am_l_acct"));
    

public class AddressConfiguration : EntityTypeConfiguration<Address>

    public AddressConfiguration()
        : base()
    
        HasKey(p => p.AccountNumber);
        Property(p => p.AccountNumber).
            HasColumnName("am_l_acct").
            IsRequired();

        ...
    

外键映射只在一侧完成。如果不是因为外键列也是表的主键,这似乎会起作用。当我尝试运行查询时,出现错误:

(256,6):错误 0019:类型中的每个属性名称必须是唯一的。属性名称“am_l_acct”已定义。

很遗憾,我无法从 Address 实体中提取 AccountNumber 属性的映射,因为它是主键。

有没有办法可以完成这个映射,还是不可能?

【问题讨论】:

【参考方案1】:

从您的 Customer 映射中删除此 Map(x =&gt; x.MapKey("am_l_acct"))。仅当您映射想要在数据库中定义 FK 列并且您在类中没有 FK 属性但您拥有它时才使用此映射 - 它是 Address 实体中的主键。如果您尝试以这种方式映射 FK,EF 认为您正在尝试创建具有相同名称的列。

【讨论】:

哇,谢谢。我现在觉得有点傻。我确实尝试过,但我想当我这样做时,我没有将属性设置为虚拟,所以它没有延迟加载并且我得到了 NullReferenceException。现在效果很好。

以上是关于实体框架 4.1 代码优先映射到将主键作为外键列的表的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 4.1 代码优先外键 ID

将主键修改为外键时出错

可以将@Id添加到映射到Spring boot Jpa中没有主键列的表的实体吗?

如何在Django中加入非主键和外键列的查询

实体框架4.1代码优先映射问题

使用实体框架 4.1 代码优先方法将一对一的表关系映射到单个实体