写在之前:
在结束了了长达半年之久的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)
![]() |
|
d.多张表映射到一个对象(Splitting a entity Across Multiple Table)0…
|
|
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)
如左图将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的值对于特定的操作不是很重要的话,最好创建一个默认值,防止出错。
![]()
|
|
操作步骤:将表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();
}
}