我想要这个连接表,它有 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;}
}
因此,我尝试将连接表指定为在数据库上下文中定义多对多关系时使用的表:
builder.Entity<GroceryItem>()
.HasMany(p => p.Establishments)
.WithMany(p => p.VeganItems)
.UsingEntity(j => j.ToTable("GroceryItemGroceryStores"));
有些事情不太对劲,因为我在运行时收到此错误
dotnet ef migrations add InitialCreate
:
无法将表“GroceryItemGroceryStores”用于实体类型 'GroceryItemGroceryStore' 因为它用于实体类型 'GroceryItemGroceryStore (Dictionary
)' 并可能 其他实体类型,但不存在链接关系。添加一个 主键属性上“GroceryItemGroceryStore”的外键 并指向映射到的另一个实体上的主键 'GroceryItemGroceryStores'.
我哪里出错了?
编辑 - 插入数据时出现问题
表已全部创建成功。但是,在插入已建立的
GroceryItemGroceryStores
后,GroceryStores
表和 GroceryItem
表不会获得任何插入。
以下是发送的有效负载,用于添加
GroceryItem
,还应添加 GroceryStore
和 GroceryItemGroceryStore
:
{
"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
模型中已经通过连接实体GroceryItem
将GroceryStore
和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);
编辑:
您应该从
Establishments
模型中删除 VeganItem
属性,并从 VeganItems
模型中删除 Establishment
属性。否则,他们将通过单独的联接表创建单独的多对多关系。
编辑 - 用于插入数据
请按照以下步骤操作 -
GroceryStore
(例如newStore
)GroceryItem
(例如newItem
)newItem.GroceryItemGroceryStores = new List<GroceryItemGroceryStore>
{
new GroceryItemGroceryStore { GroceryStoreId = newStore.Id }
};
_context.GroceryItems.Add(newItem);
await _context.SaveChangesAsync();