如何使用实体框架fluent API配置多对多关系

本文关键字:配置 关系 API fluent 何使用 实体 框架 | 更新日期: 2023-09-27 18:20:59

我试图首先在EF代码中建立一个多对多关系,但默认约定出错了。以下类别描述了这种关系:

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}
class Account
{        
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

一个帐户可以有多个产品

然而,EF约定将创建DB表作为:

Products Table
--------------
Id
Name
Account_Id  <- What is this?
Accounts Table
--------------
Id
Name

这看起来不像是多对多表结构?如何配置fluent API来反映关系并创建一个中介表:

AccountProducts Table
---------------------
Account_Id
Product_Id

如何使用实体框架fluent API配置多对多关系

modelBuilder.Entity<Account>()
            .HasMany(a => a.Products)
            .WithMany()
            .Map(x =>
            {
                x.MapLeftKey("Account_Id");
                x.MapRightKey("Product_Id");
                x.ToTable("AccountProducts");
            });
EF提出的是一对多关系。

一个帐户可以有多个产品,即每个产品都有一个Account_Id

如果你想要一个多对多的关系(并创建一个中间表),下面的方法应该可以使用

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Account> Accounts { get; set; }
}
class Account
{        
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

代码首先是以正确的关系方式创建表。当

一个帐户可以有多个产品。

Products表应该存储其Account的密钥,就像它现在实际做的那样。

你试图在数据库中看到的是多对多的关系,而不是一对多。如果你想先用代码实现这一点,你应该重新设计你的实体

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Account> Accounts { get; set; }
}
class Account
{        
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

在这种情况下,一个产品可以有许多帐户,一个帐户可以有许多产品。

        public AccountProductsMap()
    {
        this.ToTable("AccountProducts");
        this.HasKey(cr => cr.Id);
        this.HasMany(cr => cr.Account)
            .WithMany(c => c.Products)
            .Map(m => m.ToTable("AccountProducts_Mapping"));
    }