zoukankan      html  css  js  c++  java
  • entityframework学习笔记--004-无载荷与有载荷关系

    1.无载荷(with NO Payload)的多对多关系建模

    在数据库中,存在通过一张链接表来关联两张表的情况。链接表仅包含连接两张表形成多对多关系的外键,你需要把这两张多对多关系的表导入到实体框架模型中。

    1.1 假设我们有如下数据关系:

    我们有三张表用来存储Album(专辑)、Artist(艺人)、LinkTable(专辑与艺人的关系表)。一张“专辑”可以有多个“艺人”,同时一个“艺人”也可以有多张专辑。

    1.2 右键你的项目,使用entityframework的database first创建实体模型。注意把这三张表都选上,当点击“完成”之后,实体框架生成的视图如图4-1

    图4-1

    1.3 观察图4-1可以发现,Album与Artist之间的关系被映射成了一条多对多的直线,而当初选择的LinkTable表没有出现在视图中。这是因为LinkTable中没有标量属性,也就是说没有载荷。实体框架认为,LinkTable存在的意义就是表示Album与Artist之间的关系的,而上图足以表示他两的关系,所以LinkTable就没有存在的必要了。但是如果LinkTable中有标量属性,实体框架则会为他创建相应的模型,如下一节2.1。

    1.4 对上述关系的插入与查询测试。输出如图4-2

     1 using (var context = new ef6recipesEntities())
     2             {
     3 
     4                 // 添加一个拥有两张专辑的艺术家 
     5                 var artist = new Artist { FirstName = "Alan", LastName = "Jackson" };
     6                 var album1 = new Album { AlbumName = "Drive" };
     7                 var album2 = new Album { AlbumName = "Live at Texas Stadium" };
     8                 artist.Albums.Add(album1);
     9                 artist.Albums.Add(album2);
    10                 context.Artists.Add(artist);
    11 
    12                 //添加两个艺术家的专辑
    13                 var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
    14                 var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
    15                 var album = new Album { AlbumName = "Honkytonk University" };
    16                 artist1.Albums.Add(album);
    17                 artist2.Albums.Add(album);
    18                 context.Artists.Add(artist1); 
    19                 context.Artists.Add(artist2);
    20 
    21                 context.SaveChanges();
    22             }
    23 
    24             using (var context = new ef6recipesEntities())
    25             {
    26                 Console.WriteLine("Artists and their albums...");
    27                 var artists = context.Artists;
    28                 foreach (var artist in artists)
    29                 {
    30                     Console.WriteLine("{0} {1}", artist.FirstName, artist.LastName);
    31                     foreach (var album in artist.Albums)
    32                     {
    33                         Console.WriteLine("	{0}", album.AlbumName);
    34                     }
    35                 }
    36                 Console.WriteLine("
    Albums and their artists...");
    37                 var albums = context.Albums;
    38                 foreach (var album in albums)
    39                 {
    40                     Console.WriteLine("{0}", album.AlbumName);
    41                     foreach (var artist in album.Artists)
    42                     {
    43                         Console.WriteLine("	{0} {1}", artist.FirstName, artist.LastName);
    44                     }
    45                 }
    46             }
    View Code

    图4-2

    2 有载荷的多对多关系建模

     在数据库中,存在通过一张链接表来关联两张表的情况。链接表除了包含连接两张表形成多对多关系的外键外,还包含一些额外的属性,你需要把这两张多对多关系的表导入到实体框架模型中。

    2.1 假设我们有如下关系:

     

    一个订单(Order)可以拥有多个订单项(Item),一个订单项(Item)可以属于多个订单(Order),在连接Order、Item实例的关系上有一个Count属性,这个属性被称为一个有效载荷。

    2.2 和上节的一样,右键你的项目,使用entityframework的database first创建实体模型。注意把这三张表都选上,当点击“完成”之后,实体框架生成的视图如图4-2-1

    图4-2-1

    2.3 观察上图可以发现与上节生成的视图有些不同。这次生成的视图好像更符合数据库中标的结构一样。Order与Item之间的多对多关系,被映射成两个一对多的关系,即Order与OrderItem的一对多、Item与OrderItem的一对多。

    2.4 对上述关系的插入与查询测试。输出如图4-2-2

     1 using (var context = new ef6recipesEntities1())
     2             {
     3                 var order = new Order
     4                 {
     5                     OrderId = 1,
     6                     OrderDate = new DateTime(2010, 1, 18)
     7                 };
     8                 var item = new Item
     9                 {
    10                     SKU = 1729,
    11                     Description = "Backpack",
    12                     Price = 29.97
    13                 };
    14                 var oi1 = new OrderItem { Order = order, Item = item, Count = 1 };
    15                 item = new Item
    16                 {
    17                     SKU = 2929,
    18                     Description = "Water Filter",
    19                     Price = 13.97
    20                 };
    21                 var oi2 = new OrderItem { Order = order, Item = item, Count = 3 };
    22                 item = new Item
    23                 {
    24                     SKU = 1847,
    25                     Description = "Camp Stove",
    26                     Price = 43.99
    27                 };
    28                 var oi3 = new OrderItem { Order = order, Item = item, Count = 1 };
    29                 context.OrderItems.Add(oi1);
    30                 context.OrderItems.Add(oi2);
    31                 context.OrderItems.Add(oi3);
    32                 context.SaveChanges();
    33             }
    34 
    35             using (var context = new ef6recipesEntities1())
    36             {
    37                 foreach (var order in context.Orders)
    38                 {
    39                     Console.WriteLine("Order # {0}, ordered on {1}",
    40                                        order.OrderId.ToString(),
    41                                        order.OrderDate.ToShortDateString());
    42                     Console.WriteLine("SKU	Description	Qty	Price");
    43                     Console.WriteLine("---	-----------	---	-----");
    44                     foreach (var oi in order.OrderItems)
    45                     {
    46                         Console.WriteLine("{0}	{1}	{2}	{3}", oi.Item.SKU,
    47                                            oi.Item.Description, oi.Count.ToString(),
    48                                            oi.Item.Price.ToString("C"));
    49                     }
    50                 }
    51             } 
    View Code

    图4-2-2

    最后,虽然ef支持无载荷模式,但是在项目中最好不要使用,因为一旦以后要把无载荷改成有载荷模式,实体关系也要随之改变、程序代码也要随之改变,这样造成很多不必要的麻烦。有一个好的解决办法是,在项目的一开始就使用有载荷模式,即使我们的表在一开始是无载荷,我们也可以给他加一个随机的属性,使之变成有载荷模式。

  • 相关阅读:
    实现qsort(和qsort差一个数量级啊,伤自尊了)
    广度优先遍历目录(Windows平台、C++)
    在CentOS上以源码编译的方式安装Greenplum数据库
    Java泛型函数的运行时类型检查的问题
    Android代码的几点小技巧
    关于矢量图片资源向后兼容:CompatVectorFromResourcesEnabled标志的使用
    指定Android Studio编译工程时的源文件编码
    安卓日历同步的一些要点
    Android Studio编译错误:Unexpected lock protocol found in lock file. Expected 3, found 0.
    系统信息命令
  • 原文地址:https://www.cnblogs.com/renjing/p/6118721.html
Copyright © 2011-2022 走看看