问题描述
我想要这个连接表,它有 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
我哪里出错了?
编辑 - 插入数据时出现问题
表已全部创建成功。但是,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();