EF Core 多对多连接 Table,额外属性不起作用

EF Core Many to Many Join Table with Extra Properties Not Working

我想要这个连接 table,它有 2 个外键,但也添加了一些其他属性:

[Serializable]
public class GroceryItemGroceryStore
{
    [Key, Column(Order = 0), Required]
    public int GroceryItemId { get; set; }
    [Key, Column(Order = 1), Required]
    public int GroceryStoreId { get; set; }

    public virtual GroceryItem GroceryItem { get; set; }
    public virtual GroceryStore GroceryStore { get; set; }

    [Required]
    public int NotInEstablishmentCount { get; set; }
    [Required]
    public int InEstablishmentCount { get; set; }
    [Required]
    public double Price { get; set; }
}

加入这些实体:

public class GroceryItem : VeganItem<GroceryItemTag, GroceryStore>
{
    public GroceryItem(string name, string brand, string description, string image)
    {
        this.Name = name;
        this.Brand = brand;
        this.Description = description;
        this.Image = image;
    }

    [Required]
    public string Name { get; set; }
    [Required]
    public string Brand { get; set; }
    [Required]
    public string Description { get; set; }
    public string Image { get; set; }
    public virtual ICollection<GroceryItemGroceryStore> GroceryItemGroceryStores { get; set; }
}

[Serializable]
public abstract class VeganItem<VeganItemTagType, EstablishmentType>
{
    public int Id { get; set; }
    [Required]
    public int IsNotVeganCount { get; set; }
    [Required]
    public int IsVeganCount { get; set; }
    [Required]
    public int RatingsCount { get; set; }
    [Required]
    public int Rating { get; set; }
    [Required]
    public List<VeganItemTagType> Tags { get; set; }
    //[Required]
    public List<EstablishmentType> Establishments { get; set; }
    [Required]
    public int CurrentRevisionId { get; set; }
}

和这些实体:

[Serializable]
public class GroceryStore : Establishment<GroceryItem>
{
    public GroceryStore(string name, string placeId, string street, string suburb, string city, string streetNumber)
    {
        this.Name = name;
        this.PlaceId = placeId;
        this.Street = street;
        this.StreetNumber = streetNumber;
        this.City = city;
        this.Suburb = suburb;
    }
}

[Serializable]
public abstract class Establishment<VeganItemType>
{
    public int Id {get; set;}
    [Required]
    public string Name {get; set;}
    [Required]
    public string PlaceId {get; set;}
    [Required]
    public string Street {get; set;}
    public string Suburb {get; set;}
    public string City {get; set;}
    
    public List<VeganItemType> VeganItems {get; set;}
    public string StreetNumber {get; set;}
}

所以我尝试将我的连接 table 指定为 table 以在我的数据库上下文中定义我的多对多关系时使用:


builder.Entity<GroceryItem>()
    .HasMany(p => p.Establishments)
    .WithMany(p => p.VeganItems)
    .UsingEntity(j => j.ToTable("GroceryItemGroceryStores"));   

  

有些不对劲,因为我在 运行 dotnet ef migrations add InitialCreate:

时收到此错误

Cannot use table 'GroceryItemGroceryStores' for entity type 'GroceryItemGroceryStore' since it is being used for entity type 'GroceryItemGroceryStore (Dictionary<string, object>)' and potentially other entity types, but there is no linking relationship. Add a foreign key to 'GroceryItemGroceryStore' on the primary key properties and pointing to the primary key on another entity typed mapped to 'GroceryItemGroceryStores'.

我哪里错了?

编辑 - 插入数据时出现问题
table 已全部创建成功。但是,GroceryItemGroceryStores table 和 GroceryStores table 在插入一个已建立的 GroceryItem 后没有得到任何插入。

以下是发送的有效载荷以添加 GroceryItem,其中还应添加 GroceryStoreGroceryItemGroceryStore

{
    "name": "yummy fofod",
    "brand": "goodfoobdgffe",
    "description": "dfsad",
    "establishments": [{
        "name": "Macdonalds",
        "street": "Beach Rd",
        "placeId": "fsadfsdfsdfsdfsadfsadfsdf"
    }],
    "tags": [
        {
            "name": "sdf",
            "id": "9",
            "iconCodePoint": 23145
        }
    ]
}

这是处理上述负载请求的控制器:

[HttpPost]
public async Task<ActionResult<GroceryItem>> PostGroceryItem(GroceryItem groceryItem)
{
    _context.GroceryItems.Add(groceryItem);
    await _context.SaveChangesAsync();

    return CreatedAtAction("GetGroceryItem", new { id = groceryItem.Id }, groceryItem);
}

存在以下两个属性-

public virtual GroceryItem GroceryItem { get; set; }
public virtual GroceryStore GroceryStore { get; set; }

GroceryItemGroceryStore模型中已经通过连接实体GroceryItemGroceryStore.

GroceryItemGroceryStore置于多对多关系中

那么你的关系配置代码试图在它们之间创建一个新的多对多关系,但试图使用相同的连接实体。这就是问题所在,这正是错误消息所说的内容。

删除配置代码,它应该会自动运行。

如果要手动配置关系,则改为-

builder.Entity<GroceryItemGroceryStore>()
    .HasOne(p => p.GroceryItem)
    .WithMany(p => p.GroceryItemGroceryStores)
    .HasForeignKey(p=> p.GroceryItemId);
    
builder.Entity<GroceryItemGroceryStore>()
    .HasOne(p => p.GroceryStore)
    .WithMany()
    .HasForeignKey(p=> p.GroceryStoreId);

或者,添加以下 属性 -

会更好
public virtual ICollection<GroceryItemGroceryStore> GroceryItemGroceryStores { get; set; }

GroceryStore 模型,并将配置更改为 -

builder.Entity<GroceryItemGroceryStore>()
    .HasOne(p => p.GroceryItem)
    .WithMany(p => p.GroceryItemGroceryStores)
    .HasForeignKey(p=> p.GroceryItemId);
    
builder.Entity<GroceryItemGroceryStore>()
    .HasOne(p => p.GroceryStore)
    .WithMany(p=> p.GroceryItemGroceryStores)
    .HasForeignKey(p=> p.GroceryStoreId);

编辑:
您应该从 VeganItem 模型中删除 Establishments 属性 并从 Establishment 模型中删除 VeganItems 属性。否则,他们将通过单独的连接创建一个单独的多对多关系 table.

编辑 - 用于插入数据
按照以下步骤操作 -

  1. 从您的负载
  2. 创建一个新的GroceryStore(例如newStore
  3. 将其插入数据库
  4. 从有效负载
  5. 创建一个新的GroceryItem(例如newItem
  6. 执行以下操作 -
newItem.GroceryItemGroceryStores = new List<GroceryItemGroceryStore>
{
    new GroceryItemGroceryStore { GroceryStoreId = newStore.Id }
};

_context.GroceryItems.Add(newItem);
await _context.SaveChangesAsync();