EF6秘籍2th:实体数据建模基础(七)建模有标量属性的多对多关系-创新互联
问题:
10年积累的网站设计制作、成都网站设计经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先做网站设计后付款的网站建设流程,更有望奎免费网站建设让你可以放心的选择与我们合作。在数据库的链接表中除了原有的外键列之外,还有其他的数据列。现在想把链接表及其关联表导入到EDM中,以形成一个多对多关系或2个一对多关系。
解决方案:
EF不支持带有属性的关联。如果链接表包含有除了外键之外的其他列,EF将产生一个单独的实体类型以表示这个链接表。最终的模型将包含一个链接表实体类型和2个一对多的关联。
数据库图表如下:
数据库脚本如下:
use [EF6Recipes] go create table Chapter2.Item( SKU int primary key, [Description] varchar(50) not null, Price decimal(18,2) not null); create table Chapter2.[Order]( OrderId int identity primary key, OrderDate datetime not null); create table Chapter2.OrderItem( OrderId int foreign key references Chapter2.[Order](OrderId), SKU int foreign key references Chapter2.Item(SKU), [Count] int not null, constraint PK_OrderItem primary key (OrderId,SKU));
一个订单(Order)能有多个项(Item),一个项也能包含在多个订单里。另外,还有一个Count属性关联到每个订单与项的实例。这个Count属性就被称为负载(Payload)。
操作步骤同EF6 秘籍 2th:实体数据建模基础 (五)从现有数据库生成模型一致,不再重复。
生成的EDM如下图:
原理:
EF不支持带有其他属性列的关联。它将转换这个链接表为一个包含2个一对多关联的实体。在这种情况下,OrderItem表没有被转换成一个关联,而是转换为一个1对多关联到Order和一个1对多关联到Item的实体类型。
额外属性列的增加需要关联表的实体提供一个额外的跳板以获取相关的项。
using (var context = new EF6RecipesContext()) { var oiList = new List(); var order1 = new Order { OrderDate = new DateTime(2010, 1, 18) }; var order2 = new Order { OrderDate = new DateTime(2010, 1, 19) }; var item1 = new Item { SKU = 1729, Description = "Backpack", Price = 29.97M }; var item2 = new Item { SKU = 2929, Description = "Water Filter", Price = 13.97M }; var item3 = new Item { SKU = 1847, Description = "Camp Stove", Price = 43.99M }; oiList.Add(new OrderItem { Order = order1, Item = item1, Count = 1 }); oiList.Add(new OrderItem { Order = order1, Item = item2, Count = 3 }); oiList.Add(new OrderItem { Order = order1, Item = item3, Count = 1 }); oiList.Add(new OrderItem { Order = order2, Item = item1, Count = 2 }); oiList.Add(new OrderItem { Order = order2, Item = item2, Count = 2 }); oiList.Add(new OrderItem { Order = order2, Item = item3, Count = 2 }); context.OrderItems.AddRange(oiList); context.SaveChanges(); } using (var context = new EF6RecipesContext()) { foreach (var order in context.Orders) { Console.WriteLine("Order # {0}, orderd on {1}", order.OrderId, 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.SKU, oi.Item.Description, oi.Count, oi.Item.Price); } } }
运行结果如下:
该代码与原文提供的程序不一样,原文提供的代码我执行的时候只插入了Order的数据,附原文代码:
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.Add(order); context.SaveChanges();
最佳实践:
由于链接表有负载和没有负载,生成的模型完全不同。这就需要我们在设计之初就需要分析链接表会不会有其他列的可能,如果不能确定,使用一个自增列。这样的话就会生成一个包含2个1对多关系的实体类型。在以后进行其他属性列扩展时,对模型的影响最小。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
网页名称:EF6秘籍2th:实体数据建模基础(七)建模有标量属性的多对多关系-创新互联
地址分享:http://azwzsj.com/article/dgcgie.html