对于使用实体框架和建立实体之间的关系有疑问。
我想要实现的是在一个单独的实体中的集合中有重复项。

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的子集)建模,必须引入一个新的类OrderMenuItemOrder具有此新类型ItemsOrderMenuItem集合(不是直接属于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的连接表的新的多对多关系。

10-04 16:37