对于使用实体框架和建立实体之间的关系有疑问。
我想要实现的是在一个单独的实体中的集合中有重复项。
List<MenuItem> menuItems = new List<MenuItem>();
MenuItem m1 = menuRepository.GetItemByCode("001");
MenuItem m2 = menuRepository.GetItemByCode("001"); //same item but want to store it additionally as m2.MenuItemExtras will be different from m1.MenuItemExtras
menuItems.Add(m1);
menuItems.Add(m2);
Order order = new Order();
order.MenuItems = menuItems;
orderRepository.Save(order);
这个工作正常,但我只将一条记录插入表
即
OrderMenuItem
OrderPK = 1, MenuItemPK = 1 //Id of menuItem with code "001"
我可能想要的是这样的:
OrderMenuItem表包含具有其自己的主键的第三列,而不是OrderPK和MenuItemPK的组合。即
OrderMenuItem
OrderMenuItemId = 1, OrderPK = 1, MenuItemPK = 1
OrderMenuItemId = 2, OrderPK = 1, MenuItemPK = 1
不确定如何实际实现此目标以及我是否需要重新定义班级关系。感谢您的任何意见。
以下是DbContext的类和摘要:
public class Order
{
public Guid OrderId { get; set; }
public virtual ICollection<MenuItem> MenuItems { get; set; }
public Order()
{
MenuItems = new Collection<MenuItem>();
}
}
public class MenuItem
{
public Guid MenuItemId { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int SortOrder { get; set; }
public virtual ICollection<MenuItemExtras> MenuItemExtras { get; set; }
}
public class MenuItemCategory
{
public Guid MenuItemCategoryId { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public string HotKey { get; set; }
public int SortOrder { get; set; }
public virtual ICollection<MenuItem> MenuItems { get; set; }
}
public class MenuItemExtras
{
public Guid MenuItemExtrasId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
在OnModelCreating ovveride的DbContext中,我具有以下内容:
modelBuilder.Entity<MenuItemCategory>().Property(m => m.MenuItemCategoryId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<MenuItemCategory>().HasMany(m => m.MenuItems).WithMany();
modelBuilder.Entity<MenuItem>().Property(m => m.MenuItemId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<MenuItem>().HasMany(m => m.MenuItemExtras).WithMany();
modelBuilder.Entity<MenuItemExtras>().Property(m => m.MenuItemExtrasId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Order>().Property(o => o.OrderId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Order>().HasMany(m => m.MenuItems).WithMany();
生成下表:
MenuItem
MenuItemCategory
MenuItemCategoryMenuItem
MenuItemExtras
MenuItemMenuItemExtras
Order
OrderMenuItems
最佳答案
我们在这里谈论的是Pizza&Co.,而不是下拉菜单,对吧?
根据我的理解,您必须区分MenuItem
可能具有的附加功能与客人希望与订购的MenuItem
一起实际订购的附加功能。MenuItem
类可以保持不变,它描述了餐厅为特定MenuItem
提供的所有可能的其他功能:
public class MenuItem // Pizza Margherita
{
// ...
public virtual ICollection<MenuItemExtras> MenuItemExtras { get; set; }
// Possible Extras: Paprika or Ham or Mushrooms
}
但是,要对有序的Extras(我希望它是可能的Extras的子集)建模,必须引入一个新的类
OrderMenuItem
。 Order
具有此新类型Items
的OrderMenuItem
集合(不是直接属于MenuItem
):public class Order
{
public Guid OrderId { get; set; }
public virtual ICollection<OrderMenuItem> Items { get; set; }
}
OrderMenuItem
引用来宾已订购的MenuItem
,并且来宾已从所有可能的Extras中选择了MenuItemExtras
的集合:public class OrderMenuItem
{
public int OrderMenuItemId { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; }
public int MenuItemId { get; set; }
public MenuItem MenuItem { get; set; } // Pizza Margherita
public ICollection<MenuItemExtras> MenuItemExtras { get; set; }
// Ordered Extras: Paprika and Mushrooms (subset of Possible Extras)
}
新的关系可以这样定义:
modelBuilder.Entity<OrderMenuItem>()
.HasRequired(o => o.Order)
.WithMany(o => o.Items)
.HasForeignKey(o => o.OrderId);
modelBuilder.Entity<OrderMenuItem>()
.HasRequired(o => o.MenuItem)
.WithMany() // a MenuItem can be ordered in many orders
.HasForeignKey(o => o.MenuItemId);
modelBuilder.Entity<OrderMenuItem>()
.HasMany(o => o.MenuItemExtras)
.WithMany() // an Extra can be ordered in many orders
.Map(m => {
m.ToTable("OrderMenuItemMenuItemExtras");
m.MapLeftKey("OrderMenuItemId");
m.MapRightKey("MenuItemExtraId");
});
OrderMenuItem
表将具有其自己的主键OrderMenuItemId
和两个外键,一个键指向Order
,一个键指向MenuItem
-如您所愿。与订购的Extras的关系是带有名为OrderMenuItemMenuItemExtras
的连接表的新的多对多关系。