3

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

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 的组合。IE

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
4

1 回答 1

1

我们在这里谈论的是 Pizza & Co.,而不是下拉菜单,对吧?

在我的理解中,您必须区分可能拥有的额外服务和客人想要与订购MenuItem的实际订购MenuItem的额外服务。

该类MenuItem可以保持不变,它描述了餐厅为特定对象提供的所有可能的MenuItemExtras :

public class MenuItem // Pizza Margherita
{
    // ...
    public virtual ICollection<MenuItemExtras> MenuItemExtras { get; set; }
    // Possible Extras: Paprika or Ham or Mushrooms
}

但是要对有序的Extras 进行建模(我希望它是可能的Extras 的一个子集),您必须引入一个新的 class OrderMenuItem。AnOrder有一个Items这种新类型的集合OrderMenuItem(不是直接的MenuItem):

public class Order
{
    public Guid OrderId { get; set; }
    public virtual ICollection<OrderMenuItem> Items { get; set; }
}

参考OrderMenuItem了客人所订购的客人,并从所有可能的 Extras 中选择了客人MenuItem的集合: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.

于 2013-03-24T13:54:45.513 回答