entity-framework - Entity Framework : create one-to-one relation to itself

标签 entity-framework ef-code-first code-first

我有实体 Contact 必须链接到它自己,而不是在分层模式中

public partial class Contact 
{
  [Key, Column(Order = 0)]
  public int AgentId { get; set; }
  [Key, Column(Order = 1)]
  public int ContactId { get; set; }
  public virtual Contact Opposite { get; set; }
  public ..... many other properties
}

每个联系人都有对面Contact已链接 ON c1.AgentId = c2.ContactId AND c1.ContactId = c2.AgentId .
相反的接触是可选的,但当它存在时,它们是一对一的。不是亲子关系。
此关系的名称必须是 Opposite .我已经在 Contact 申报了属性(property)类(class)。现在我正在尝试设置关系,但这不起作用,我觉得我不知道如何正确设置它。请指教?
public class EFDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        Action<ForeignKeyAssociationMappingConfiguration> mapKey = x => x.MapKey("ContactId", "AgentId");
        modelBuilder.Entity<Contact>().HasOptional<Contact>(c => c.Opposite).WithRequired().Map(mapKey);
    }
}

最佳答案

当您使用主键作为关系的外键时,关系不能是可选的,因为主键不能有 NULL值。外键将始终具有值 - 比如说 ( ContactId = 1, AgentId = 2) - 如果具有 ( AgentId = 1, ContactId = 2) 的行没有违反外键约束存在。

但是对于必需的关系,您只能拥有成对的行,并且根本不可能将任何有意义的行插入到数据库表中,因为它总是会违反外键约束:插入行 ( AgentId = 1, ContactId = 2) 行 ( AgentId = 2, ContactId = 1) 必须存在,反之亦然。您可以插入的唯一可能的行是这样的行 (AgentId = 1, ContactId = 1),即 Opposite contact 是联系人本身。

为了实现可选关系,您需要单独的外键:

public partial class Contact 
{
    [Key, Column(Order = 0)]
    public int AgentId { get; set; }
    [Key, Column(Order = 1)]
    public int ContactId { get; set; }

    [ForeignKey("Opposite"), Column(Order = 2)]
    public int? OppositeContactId { get; set; }
    [ForeignKey("Opposite"), Column(Order = 3)]
    public int? OppositeAgentId { get; set; }

    public virtual Contact Opposite { get; set; }

    //...
}

这是一对多的关系。使用 Fluent API 而不是数据注释,它将是:
modelBuilder.Entity<Contact>()
    .HasOptional(c => c.Opposite)
    .WithMany()
    .HasForeignKey(c => new { c.OppositeContactId, c.OppositeAgentId });

在 EF 方面,您不能使其成为一对一的关系。您只能在数据库中的复合外键上添加唯一索引,以确保没有两个联系人具有相同的对立面。

关于entity-framework - Entity Framework : create one-to-one relation to itself,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14424172/

相关文章:

sql-server - 代码优先 Entity Framework 可以在同一个机器上使用 SQL Server DB 进行跨数据库查询吗?

entity-framework - Entity Framework 6 代码优先 : setting unicode to false for string properties

c# - 如何首先在 Entity Framework 代码中设置身份主键的起始值?

.net - 添加迁移给出文件名已经存在

c# - 合并两个 linq 表达式

c# - WPF MVVM 中的 ADO.NET Entity Framework ?

c# - Entity Framework 如何访问关联?

entity-framework-4.1 - Entity Framework 代码首次迁移 - 好或坏

entity-framework - EF Code First验证唯一属性?

c# - EF SaveChanges 优化?