2013-03-23 157 views
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的组合。即

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; } 
} 

在我的DbContext我OnModelCreating ovveride我有以下几点:

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

我们在这里谈论披萨& Co. t关于下拉菜单,对吧?

在我的理解,你必须在可能额外一个MenuItem可以与实际下令额外的客人想要与有序MenuItem在一起有区别。

MenuItem类可以保持不变,它描述了一个特定的MenuItem所有可能额外餐厅提供:

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

但对有序附加功能(这是我所期望的是一个子集建模的可能其他)你必须引入一个新的类OrderMenuItem。一个Order对这一新类型OrderMenuItemItems集合(不是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和一个键MenuItem - 如您所料。与订购的Extras的关系是一个与名为OrderMenuItemMenuItemExtras的连接表的新的多对多关系。

+0

感谢您的反馈意见。是的,这是正确的,我发布了一些问题后,我发现了一个完美的例子,那就是Northwind数据库,它具有相同的功能,并且引入了第三个称为orderdetails的表,它是您建议的产品集合。再次感谢。 – user2203366 2013-03-24 20:20:29