具有重复子项的多对多关系实体框架

时间:2013-03-23 22:45:42

标签: c# entity-framework-5

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

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

1 个答案:

答案 0 :(得分:1)

我们正在谈论披萨&amp;在这里,不是关于下拉菜单,对吗?

根据我的理解,您必须区分{em>可能的额外内容MenuItem可以拥有的实际有序额外内容,客人希望与订购的{{ {1}}。

MenuItem课程可以保持不变,它会描述一家餐馆为特定MenuItem提供的所有可能的额外内容:

MenuItem

但是为了模拟有序的 Extras(我希望它是可能的 Extras的一个子集),你必须引入一个新的类public class MenuItem // Pizza Margherita { // ... public virtual ICollection<MenuItemExtras> MenuItemExtras { get; set; } // Possible Extras: Paprika or Ham or Mushrooms } OrderMenuItem包含Order这种新类型Items的集合(不直接属于OrderMenuItem):

MenuItem

public class Order { public Guid OrderId { get; set; } public virtual ICollection<OrderMenuItem> Items { get; set; } } 引用了客人订购的OrderMenuItem以及客人从所有可能的附加内容中选择的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 - 正如您所期望的那样。与有序Extras的关系是一个新的多对多关系,其中一个名为MenuItem的连接表。