第二章(4)建立负载的多对多模型
问题:
在你的多对多关系中,中间链接表包含了一些负载数据(也就是除了外键之外还有其他附加列)。现在你想要创建一个用两个一对多的关联代表多对多关联的模型。
解决过程:
如果连接表含有额外的信息列,EF会为它创建一个新的实体类型。所以结果就成了,这个模型包含了两个一对多的关系。假设我们的表关联如图2-4-1所示。
图2-4-1
一个Oder可能有很多Item,一个Item可能会出现在很多Order中。另外,在中间表OderItem中我们还多了一个Count的属性,这个属性也就负载属性。创建这样的模型,需要做的事情有:
- 在你的项目上右键,选择“添加新项”,在弹出的Visual C# Data Templates中选择ADO.NET Entity Data Model。
- 选择从数据库中生成,点击下一步。
- 使用向导创建一个新的连接或者是选择已有数据库连接。
- 在下一步的Choose Your Database Object 的对话框中,选择表Order、OrderItem和Item。保持最下面的两个复选框为选中状态。
结果创建出来的模型如图2-4-2所示:
图2-4-2
原理:
在这一节的例子里,OrderItem表代表的不仅仅是一个衔接关系,而是一个实体,它和Order表、Item表有一对多关系。而上一章节的中间链表因为没有负载属性,所以并没有把转换成实体类,而变成了多对多关系的一部分。通过带负载的中间表在实体间连接取数据时,需要多加“一跳”,这在下面的代码中有所体现:
插入记录的代码
using (var context = new EFRecipesEntities()) { var order = new Order { OrderId = 1, OrderDate = new DateTime(2010, 1, 18) }; var item = new Item { SKU = 1729, Description = "Backpack", Price = 29.97M }; var oi = new OrderItem { Order = order, Item = item, Count = 1 }; item = new Item { SKU = 2929, Description = "Water Filter", Price = 13.97M }; oi = new OrderItem { Order = order, Item = item, Count = 3 }; item = new Item { SKU = 1847, Description = "Camp Stove", Price = 43.99M }; oi = new OrderItem { Order = order, Item = item, Count = 1 }; context.Orders.AddObject(order); context.SaveChanges(); }
查询显示代码
using (var context = new EFRecipesEntities()) { foreach (var order in context.Orders) { Console.WriteLine("Order # {0}, ordered on {1}", order.OrderId.ToString(), order.OrderDate.ToShortDateString()); Console.WriteLine("SKU\tDescription\tQty\tPrice"); Console.WriteLine("---\t-----------\t---\t-----"); foreach (var oi in order.OrderItems) { Console.WriteLine("{0}\t{1}\t{2}\t{3}", oi.Item.SKU, oi.Item.Description, oi.Count.ToString(), oi.Item.Price.ToString("C")); } } }
输出
---------------------------------- Order # 1, ordered on 1/18/2010 SKU Description Qty Price --- ----------- --- ----- 1729 Backpack 1 $29.97 1847 Camp Stove 1 $43.99 2929 Water Filter 3 $13.97 ----------------------------------