Entity Framework 重复列问题
Entity Framework duplicated column issue
我有一个这样的基本模型:
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public List<Contact> Contacts { get; set; }
public Contact PrincipalContact { get; set; }
public int? PrincipalContactId { get; set; }
}
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public Account Account { get; set; }
public int? AccountId { get; set; }
}
Entity Framework 在 table Contacts
上创建两列:Account_Id
和 AccountId
.
列 AccountId
始终为空。我不知道为什么我有这种行为
使用 Entity Framework 实现此目的的正确方法是什么?我尝试添加 [ForeignKey]
属性,但它没有任何改变。
谢谢。
在一对一关系的情况下,您需要提供一些额外的
信息,以便 Code First 知道哪个实体是委托人,哪个是
依赖者。
public class Account
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public List<Contact> Contacts { get; set; }
[ForeignKey("PrincipalContact")]
public int? PrincipalContactId { get; set; }
public virtual Contact PrincipalContact { get; set; }
}
public class Contact
{
[Key]
[ForeignKey("AccountOf")]
public int Id { get; set; }
public string Name { get; set; }
public virtual Account AccountOf { get; set; }
}
Account_Id
列是由 EF 基于一对多关系自动创建的。如果您什么都不指定,按照惯例,EF 将识别您的导航 属性 被称为 Account
并且您的 ForeignKey 将被称为 AccountId
,但由于您有一个 属性 同名,EF 将其更改为 Account_Id
.
要创建您需要的两种关系,我建议您修改模型,如下所示:
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public List<Contact> Contacts { get; set; }
public Contact PrincipalContact { get; set; }
}
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public Account Account { get; set; }
public int? AccountId { get; set; }
}
然后,在您的上下文中,您可以使用 Fluent Api 显式配置关系。
public class YourContext : DbContext
{
public IDbSet<Account> Accounts { get; set; }
public IDbSet<Contact> Contacts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>()
.HasOptional(c => c.Account)
.WithMany(e => e.Contacts)
.HasForeignKey(a => a.AccountId);
modelBuilder.Entity<Account>()
.HasOptional(c => c.PrincipalContact)
.WithMany()
.Map(c => c.MapKey("PrincipalContactId"));
}
}
更新
如果你想在 Account
class 上保留 PrincipalContactId
属性,你应该这样映射关系:
modelBuilder.Entity<Account>()
.HasOptional(c => c.PrincipalContact)
.WithMany().HasForeignKey(a => a.PrincipalContactId);
我有一个这样的基本模型:
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public List<Contact> Contacts { get; set; }
public Contact PrincipalContact { get; set; }
public int? PrincipalContactId { get; set; }
}
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public Account Account { get; set; }
public int? AccountId { get; set; }
}
Entity Framework 在 table Contacts
上创建两列:Account_Id
和 AccountId
.
列 AccountId
始终为空。我不知道为什么我有这种行为
使用 Entity Framework 实现此目的的正确方法是什么?我尝试添加 [ForeignKey]
属性,但它没有任何改变。
谢谢。
在一对一关系的情况下,您需要提供一些额外的 信息,以便 Code First 知道哪个实体是委托人,哪个是 依赖者。
public class Account
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public List<Contact> Contacts { get; set; }
[ForeignKey("PrincipalContact")]
public int? PrincipalContactId { get; set; }
public virtual Contact PrincipalContact { get; set; }
}
public class Contact
{
[Key]
[ForeignKey("AccountOf")]
public int Id { get; set; }
public string Name { get; set; }
public virtual Account AccountOf { get; set; }
}
Account_Id
列是由 EF 基于一对多关系自动创建的。如果您什么都不指定,按照惯例,EF 将识别您的导航 属性 被称为 Account
并且您的 ForeignKey 将被称为 AccountId
,但由于您有一个 属性 同名,EF 将其更改为 Account_Id
.
要创建您需要的两种关系,我建议您修改模型,如下所示:
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public List<Contact> Contacts { get; set; }
public Contact PrincipalContact { get; set; }
}
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public Account Account { get; set; }
public int? AccountId { get; set; }
}
然后,在您的上下文中,您可以使用 Fluent Api 显式配置关系。
public class YourContext : DbContext
{
public IDbSet<Account> Accounts { get; set; }
public IDbSet<Contact> Contacts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>()
.HasOptional(c => c.Account)
.WithMany(e => e.Contacts)
.HasForeignKey(a => a.AccountId);
modelBuilder.Entity<Account>()
.HasOptional(c => c.PrincipalContact)
.WithMany()
.Map(c => c.MapKey("PrincipalContactId"));
}
}
更新
如果你想在 Account
class 上保留 PrincipalContactId
属性,你应该这样映射关系:
modelBuilder.Entity<Account>()
.HasOptional(c => c.PrincipalContact)
.WithMany().HasForeignKey(a => a.PrincipalContactId);