davin

Just a little thinking and interest!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

写在之前:

在结束了了长达半年之久的Java+Silverlight开发之后,再次回到纯MS平台的asp.net开发,觉得很是开心.之前的很多其它时间都花在Silverlight了,所以这次回到asp.net给自己定了一读书计划.首先自然是了c#4.0和我钟爱的Entity Framework 4.0

幸运的是,我拿到了Entity Framework 4.0 Recipes 这本书(英文版),在经历了一个个多月的scum meeting,感觉自己英语水平提高了不少,从开始每天大概写好要写的内容,到先想好要说什么,临时去组织,到现在能够即兴的表达一些观点,主要是克服了紧张 呵呵。不过依旧欠缺的是听力,不能很好follow国外的team member。不扯了,还是回到Entity Framework 4.0 Recipes ,在我看到第2章就发现例子好熟悉,才发现是Zeeshan Hirani他写的(在EF beta和1.0的时候,我看过不少他写的blog,还有他写的一个500多页的EF学习笔记)难怪如此亲切。由于之前对EF比较熟悉,所以读书笔记所包括的内容,主要是关于我不熟悉的部分和EF4.0的new feature部分,所以想了解更多的关于EF4,还是看书会比较全面。

EDM中的几种特别的关系:当然最主要需要学习的还是Complex Type,作为EF4.0中的一个重要的feature.

  a.没有负载的多对多关系 (Modeling a Many-to-Many Relationship with No Payload)   

  b.有负载的对多对多关系(Modeling a Many-to-Many Relationship with Payload)

   关于多对多关系以及伏在问题,在我08年写的blog 这篇http://www.cnblogs.com/subway-2008/archive/2008/08/20/1272375.html,中有比较详细的介绍

  c.自引用(Modeling a Self-Referencing Relationship)

R9$BHV%G%4N1E%%~~(VN{P5

~]OW@`NBA8LUBQP_HATXKUK[4]

 

如左图 PictureCategory自己应用自己,因此关联属性为Subcategories(*) and ParentCategory(0…1).对于增删查改的操作和多对多关系没有区别.如果要遍历一个节点,就只要用递归来完成。
Note:不过感觉在EF4.0里面的association 没有mapping的步骤了,记得在EF1.0里面是需要设置对象关系的mapping

 

  d.多张表映射到一个对象(Splitting a entity Across Multiple Table)0…

YNR82RMVYG6E0)R3~PXOHJP

 

[U%4~IEZDH1TOTAB3QS6`MW

 

Product和 ProductWebInfo表是主外键的关系,2个表的字段分别映射到同一个实体对象:eg

using (var context = new EFRecipesEntities())
          {
              var product = new Product { SKU = 147, Description = "Expandable Hydration Pack", Price = 19.97M, ImageURL = "/pack147.jpg" };
              context.Products.AddObject(product);
              product = new Product { SKU = 178, Description = "Rugged Ranger Duffel Bag", Price = 39.97M, ImageURL = "/pack178.jpg" };
              context.Products.AddObject(product);
              product = new Product { SKU = 186, Description = "Range Field Pack", Price = 98.97M, ImageURL = "/noimage.jp" };
              context.Products.AddObject(product);
              product = new Product { SKU = 202, Description = "Small Deployment Back Pack", Price = 29.97M, ImageURL = "/pack202.jpg" };
              context.Products.AddObject(product);

              context.SaveChanges();
          }

e.多个对象映射到一个表(Splitting a Table Across Multiple Entities)

X$KOC6{VEQ2HFBH}SD5Z81T

C4{H@V}99A`Y3H7OXY`JL}D

如左图将Photograph的bianry字段单独map到一个对象,这种做法有利于提高单个表的性能。因为将这种思想推广,对于多字段的表,将常用的字段 放在一个实体,将一些不常用或者是容量比较大的字段(bianry类型的)映射到另一个实体。记得在EF1.0的时候我也探讨过这个问题,当时觉得用存储过程是一个比较好的方式。eg:

using (var context = new EFRecipesEntities())
            {
                var photo = new Photograph { PhotoId = 1, Title = "My Dog", ThumbnailBits = thumbBits };
                var fullImage = new PhotographFullImage { PhotoId = 1, HighResolutionBits = fullBits };
                photo.PhotographFullImage = fullImage;
                context.Photographs.AddObject(photo);
                context.SaveChanges();
            }

 

f.表继承

    层次继承 hierarchy inheritance

    这个在EF1.0的时候写过一篇文章,我眼中的继承,那里面对继承讲的比较全面。

  g.实体间的is a 和has a(Molding is a and has a Relationships between two entities)

     is a是继承

    has a是navigation property

  h.复杂类型(Complex Type)这是EF4.0的new feature,在1.0版本时不支持的,   Complex Type允许你讲几个属性以族的方式加入到一个类型,并且这个类型作为实体的一个属性,Complex Type可以包含Scalar属性和其它Complex Types,但是不能作为导航属性,Complex Type不能成为Entity key.Complex types在 object Context 是不被跟踪的(tracked)

Note:Complex Type是不可以为空的,因此对于Complex Typed的值对于特定的操作不是很重要的话,最好创建一个默认值,防止出错。

 

UPQCA)GN~IRLS5IO3C4C5YJ[4]

 

_Z@@_4YB3(LHJ2WQF6M)@[O

ZT9VD3}]6KHFRI~BQ%PGBEM[4]

 

操作步骤:将表Agent加入到EDM生产一个Agent对象,然后选择LastName,FirstName属性,右键选择Refactored into Complex type,然后在模型浏览器中,重命名ComplexType1为Name,再在Agent对象上的Complex Type Property 重命名为Name.同理将AddressLine1,AddressLine2,City,State ZipcCode 属性Refactored into 到复杂类型Address。

上面是映射的图,再看代码如何对Complex Type如何访问

using (var context = new EFRecipesEntities())
          {
              var name1 = new Name { FirstName = "Robin", LastName = "Rosen" };
              var name2 = new Name { FirstName = "Alex", LastName = "St. James" };
              var address1 = new Address { AddressLine1 = "510 N. Grant", AddressLine2 = "Apt. 8", City = "Raytown", State = "MO", ZIPCode = "64133" };
              var address2 = new Address { AddressLine1 = "222 Baker St.", AddressLine2 = "Apt.22B", City = "Raytown", State = "MO", ZIPCode = "64133" };


              var nametest = new Name();
            
              context.Agents.AddObject(new Agent { Name = name1, Address = address1 });
              context.Agents.AddObject(new Agent {Name = name2, Address = address2});
              context.SaveChanges();
          }

          using (var context = new EFRecipesEntities())
          {
              Console.WriteLine("Agents");
              foreach (var agent in context.Agents)
              {
                  Console.WriteLine("{0} {1}", agent.Name.FirstName, agent.Name.LastName);
                  Console.WriteLine("{0}", agent.Address.AddressLine1);
                  Console.WriteLine("{0}", agent.Address.AddressLine2);
                  Console.WriteLine("{0}, {1} {2}", agent.Address.City, agent.Address.State, agent.Address.ZIPCode);
                  Console.WriteLine();
              }
          }

posted on 2010-11-25 23:04  davin  阅读(1083)  评论(1编辑  收藏  举报