如何在Entity FrameWork中的两个表之间创建双向关系

时间:2018-05-15 06:15:09

标签: c# entity-framework entity icollection

我有两个表,我想创建从UserContact的1-n关系,并在EF中反向。这意味着我也需要与2个目的地的2路关系它们也是基表。 用户类中的Contact表应该引入为ICollection,因此我的关系出错了,两者都是一方。check this picture但如果我删除ICollection,那么每件事情都是正确的。

我该如何解决这个问题?

  public class User
  {
    [Key]
    public Guid Id {get; set;}       
    [ForeignKey("ContactId")]
    public virtual ICollection<Contact> Contacts {get; set;}        
    public Guid? ContactId {get;set;}
  }

  public class Contact
  {
    [Key]
    public Guid Id {get; set;}
    [ForeignKey("UserId")]
    public virtual User User {get; set;}
    public Guid? UserId {get; set;}
  }

如果我删除了联系人check this picture的外键:

我希望这些表之间有一个更多的关系,但方向不同。 check this picture

3 个答案:

答案 0 :(得分:2)

有很多方法可以实现这一目标。您可以按照以下方式执行此操作

  public class User
  {
    [Key]
    public Guid Id {get; set;}
    public virtual ICollection<Contact> Contacts { get; set; }
  }

  public class Contact
  {
    [Key]
    public Guid Id {get; set;}
    public virtual User User {get; set;}
  }

您也可以尝试这种方式

  public class User
  {
    [Key]
    public Guid UserId {get; set;}
    public virtual ICollection<Contact> Contacts { get; set; }
  }

  public class Contact
  {
    [Key]
    public Guid Id {get; set;}
    public Guid UserId {get; set;}
    public virtual User User {get; set;}
  }

它包含外键属性UserId

有关详情,请访问此link

答案 1 :(得分:1)

  public class User
  {
    [Key]
    public Guid Id {get; set;}       
   // [ForeignKey("ContactId")]
    public virtual ICollection<Contact> Contacts {get; set;}        
   // public Guid? ContactId {get;set;}
  }

1-n关系的1面没有外键。

答案 2 :(得分:0)

如果您需要从用户到联系人的1-n关系,则需要其他导航属性。要确保EF行为,您还可以配置模型。 这是一个例子。

[Table("User78")]
public class User
{
    [Key]
    public int Id { get; set; }
    public virtual ICollection<Contact> Contacts { get; set; }
    public virtual User MyPreferredUser { get; set; }
}

[Table("Contact78")]
public class Contact
{
    [Key]
    public int Id { get; set; }
    public virtual User User { get; set; }
}

public class Context : DbContext
{
    public Context()
    { }

这是上下文配置

    public Context(DbConnection connection)
        : base(connection, true)
    { }

    public DbSet<User> Users { get; set; }
    public DbSet<Contact> Contacts { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .HasMany(_ => _.Contacts)
            .WithOptional(_ => _.User)
            .Map(_ => _.MapKey("UserId"));

        modelBuilder.Entity<User>()
            .HasOptional(_ => _.MyPreferredUser)
            .WithMany()
            .Map(_ => _.MapKey("ContactId"));
    }
}

在此示例中,您无法使用MyPreferredUser关系从联系人导航到用户。如果您需要,您需要添加从联系人到用户的新导航(ICollection类型)。

这是EF在迁移期间生成的DML

ExecuteNonQuery==========
CREATE TABLE [Contact78] (
 [Id] int not null identity(1,1)
, [UserId] int null
);
ALTER TABLE [Contact78] ADD CONSTRAINT [PK_Contact78_a31c6496] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [User78] (
 [Id] int not null identity(1,1)
, [ContactId] int null
);
ALTER TABLE [User78] ADD CONSTRAINT [PK_User78_a31c6496] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE INDEX [IX_UserId] ON [Contact78] ([UserId])
ExecuteNonQuery==========
CREATE INDEX [IX_ContactId] ON [User78] ([ContactId])
ExecuteNonQuery==========
ALTER TABLE [Contact78] ADD CONSTRAINT [FK_Contact78_User78_UserId] FOREIGN KEY ([UserId]) REFERENCES [User78] ([Id])
ExecuteNonQuery==========
ALTER TABLE [User78] ADD CONSTRAINT [FK_User78_User78_ContactId] FOREIGN KEY ([ContactId]) REFERENCES [User78] ([Id])