[VS2010] ADO.NET Entity Framework 新功能:永续保存无知对象 (Persistence-Ignorant Object) Overview
Posted petewell
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[VS2010] ADO.NET Entity Framework 新功能:永续保存无知对象 (Persistence-Ignorant Object) Overview相关的知识,希望对你有一定的参考价值。
ADO.NET Entity Framework 的新功能:永续保存无知对象。可以说是 Entity Framework 划时代的新功能,颠覆一般的数据组件/DAL 与数据库间的交互方式。
前一篇文章介绍了 ADO.NET Entity Framework 的模型优先设计 (Model First Design) 功能,有没有觉得 .NET Framework 4.0 中的 ADO.NET Entity Framework 进步了很多呢?如果你这样就满足了,那接下来的东西你看了可能会像某啤酒广告的女主角们那样的尖叫~
一般在设计数据类的时候,大多都是以一个纯类 (轻量级类,只声明必要的属性代表字段,并没有和其他对象交互),包含几个只针对数据做处理的属性或方法等等,若要使用它和数据库连结时,只能在里面做一些 Property Mapping,并且另外撰写数据存取的 ADO.NET 程序,这个动作只要是当过应用程序开发人员,就会觉得如呼吸般自然 … 长久以来都是如此,没有一次例外。但 ADO.NET Entity Framework 2.0 试图将这个局面颠覆过来,开发人员可以直接使用纯类对象来生成数据结构,并且由 Entity Framework 代为建立数据库以及表格,这个方式可是以前 Visual Studio 开发人员前所未见的。这个方法在 Java 阵营中已经有一些实践品,而在 Java 阵营中对轻量级的数据对象一个特别的名词:POJO (Plain-old Java Object),在 .NET 阵营也有一个相对的名词,叫 POCO (Plain-old CLR Object),用途和 POJO 差不多,但微软给了一个笔者觉得很难翻的名词: Persistence-Ignorant Object,若直接翻译会变成 “保存无知型对象”,蛮拗口的,在官方翻译未出来前,就暂时先翻成 “无差别保存对象” (编按:在 "软件构筑美学" 一书中,将此词翻译为 "永续保存无知",笔者认为这个词翻的还不错,所以引用)?好了,因为 Persistence-Ignorant Object 具有不必事先在 DBMS 中建立实例数据库,就可以利用 Entity Framework 的 DDL Generation 功能将 POCO 对象结构转换成实例数据结构以存入数据库中的能力。
笔者认为永续保存无知对象在 ADO.NET Entity Framework 乃至于 ADO.NET 甚至是整个 .NET Framework 的 Data Access 机制而言,都是一项划时代的创新,它将数据存取组件设计的刻板印象完全的改变了,没想到只使用几个属性的声明就可以生成一个完成的数据结构,这可是许多开发人员梦寐以求的功能啊,笔者一开始看到这个功能时也是眼睛一亮,试过以后更觉得它是超级好物啊~
也许这样看起来还是有点抽象,实际走一次例子就知道了。不过在做例子前,请先看看环境是否符合:
A. 已安装 Visual Studio 2010
B. 下载并安装 ADO.NET Entity Framework Feature CTP2 : http://www.microsoft.com/downloads/details.aspx?FamilyID=13FDFCE4-7F92-438F-8058-B5B4041D0F01&displayLang=en
C. 已安装 SQL Server (最好是非 Express 版本,但 Express 版也无妨)
前置作业符合后,请依下列步骤执行:
1. 在 Visual Studio 中先建立一个 AdoEF_PocoExampleLibrary 类库项目,并且加入下列类声明程序 (可同在一个类库文件或是分成个别的文件):
public class Blog
?? public Blog()
?? public int ID get; set;
?? public string Name get; set;
?? public string Url get; set;
?? public User Owner get; set;
?? public ICollection
public class Comment
?? public Comment()
?? public int ID get; set;
?? public string Title get; set;
?? public string Body get; set;
?? public Person Author get; set;
?? public Post Post get; set;
?? public DateTime Created get; set;
?? public DateTime? Posted get; set; ????
public class Person
?? public int ID get; set;
?? public string Firstname get; set;
?? public string Surname get; set;
?? public string EmailAddress get; set;
?? public ICollection
public class Post
?? public Post()
?? public int ID get; set;
?? public string Title get; set;
?? public string Body get; set;
?? public string PermaUrl get; set;
?? public DateTime Created get; set;
?? public DateTime? Posted get; set;
?? public User Author get; set;
?? public User Poster get; set;
?? public Blog Blog get; set;
?? public ICollection
?? public int BlogID get; set;
public class User : Person
?? public string Password get; set;
?? public ICollection
?? public ICollection
?? public ICollection
2. 在 Visual Studio 中建立一个 AdoEF_PocoExampleClient 主控台项目,先新增一个 BloggingModel 类,并将下列程序加入:
using System.Data.Entity;
using System.Data.EntityClient;
using System.Data.EntityModel;
using System.Data.Objects;
public class BloggingModel : ObjectContext
?? public BloggingModel(EntityConnection connection)
?????? : base(connection)
??
?????? DefaultContainerName = "BloggingModel";
??
??? public IObjectSet
??
?????? get return base.CreateObjectSet
??
??? public IObjectSet
??
?????? get return base.CreateObjectSet
??
??? public IObjectSet
??
?????? get return base.CreateObjectSet
??
??? public IObjectSet
??
?????? get return base.CreateObjectSet
??
3. 在 AdoEF_PocoExampleClient 项目中加入一个 BlogDemo 类,并将下列程序加入(其中红字为数据库连线字符串,但 initial catalog 可以指定成目前还没建的数据库名称,若你已经有 Blogs 数据库,请将 initial catalog 的名称改一下,否则执行以后,你原有的 Blogs 数据库会被删掉):
using System.Data.Entity;
using System.Data.EntityClient;
using System.Data.EntityModel;
using System.Data.Objects;
using Microsoft.Data.Objects;
class BlogDemo
?? public static void Run()
??
?????? var builder = new ContextBuilder
?????? RegisterConfigurations(builder);
?????? var connection = new SqlConnection("initial catalog=Blogs; integrated security=SSPI");
??????? using (var ctx = builder.Create(connection))
??????
?????????? if (ctx.DatabaseExists())
?????????????? ctx.DeleteDatabase();
?????????? ctx.CreateDatabase();
?????????? var EfDesign =
?????????????? new AdoEF_PocoExampleLibrary.Blog
??????????????
?????????????????? Name = "EF Design",
?????????????????? Url = "http://blogs.msdn.com/efdesign/",
?????????????????? Owner = new AdoEF_PocoExampleLibrary.User
??????????????????
?????????????????????? ID = 1,
?????????????????????? Firstname = "Johnny",
?????????????????????? Surname = "Miller",
?????????????????????? EmailAddress = "johnnyM@hotmail.com",
?????????????????????? Password = "Viking"
??????????????????
?????????????? ;
??????????? ctx.Blogs.AddObject(EfDesign);
?????????? var post = new AdoEF_PocoExampleLibrary.Post
??????????
?????????????? Title = "Hello",
?????????????? Blog = EfDesign,
?????????????? PermaUrl = EfDesign.Url + "/2009/08/Hello",
?????????????? Body = "....",
?????????????? Author = EfDesign.Owner,
?????????????? Poster = EfDesign.Owner,
?????????????? Created = DateTime.Today,
?????????????? Posted = DateTime.Today,
?????????? ;
??????????? ctx.Posts.AddObject(post);
?????????? var comment = new AdoEF_PocoExampleLibrary.Comment
??????????
?????????????? Title = "RE:" + post.Title,
?????????????? Body = "Welcome to the world of blogging Johnny...",
?????????????? Created = DateTime.Now,
?????????????? Posted = DateTime.Now,
?????????????? Post = post,
?????????????? Author = new AdoEF_PocoExampleLibrary.Person
??????????????
?????????????????? ID = 2,
?????????????????? Firstname = "Vincent",
?????????????????? Surname = "Chase",
?????????????????? EmailAddress = "vinny@hotmail.com",
??????????????
?????????? ;
??????????? ctx.Comments.AddObject(comment);
?????????? ctx.SaveChanges();
??????????? AdoEF_PocoExampleLibrary.Blog blog = ctx.Blogs.Single();
??????????? foreach (var entry in blog.Posts)
??????????
?????????????? Console.WriteLine(entry.Title);
?????????????? Console.WriteLine(entry.Author.Firstname);
??????????
??????
??
??? static void RegisterConfigurations(ContextBuilder
??
?????? builder.Configurations.Add(new CommentConfiguration());
?????? builder.Configurations.Add(new BlogConfiguration());
?????? builder.Configurations.Add(new PostConfiguration());
?????? builder.Configurations.Add(new PersonConfiguration());
?????? builder.Configurations.Add(new UserConfiguration());
??
4. 在前一步的程序的下方,加入下列的程序:
public class CommentConfiguration : EntityConfiguration
?? public CommentConfiguration()
??
?????? Property(c => c.ID).IsIdentity();
?????? Property(c => c.Title).HasMaxLength(103).IsRequired();
?????? Property(c => c.Body).IsRequired();
?????? // 1 to * relationships???????????
?????? Relationship(c => c.Author).IsRequired();
?????? Relationship(c => c.Post).IsRequired();
?????? //Register some inverses???????????
?????? Relationship(c => c.Post).FromProperty(p => p.Comments);
?????? Relationship(c => c.Author).FromProperty(u => u.Comments);
??
public class BlogConfiguration : EntityConfiguration
?? public BlogConfiguration()
??
?????? Property(b => b.ID).IsIdentity();
?????? Property(b => b.Name).HasMaxLength(100).IsRequired();
?????? Relationship(b => b.Owner).IsRequired();
?????? //Register some inverses???????????
?????? Relationship(b => b.Owner).FromProperty(u => u.Blogs);
?????? Relationship(b => b.Posts).FromProperty(p => p.Blog);
??
public class PostConfiguration : EntityConfiguration
?? public PostConfiguration()
??
?????? // Make the PK store generated???????????
?????? Property(p => p.ID).IsIdentity();
?????? // Convert some ‘0..1 to *‘ relationships into ‘1 to *‘???????????
?????? Relationship(p => p.Author).IsRequired();
?????? Relationship(p => p.Blog).IsRequired();
?????? Relationship(p => p.Poster).IsRequired();
?????? // Setup some facets???????????
?????? Property(p => p.Body).IsRequired();
?????? Property(p => p.PermaUrl).HasMaxLength(200);
?????? Property(p => p.Title).HasMaxLength(100);
?????? // Register some Inverses???????????
?????? Relationship(p => p.Author).FromProperty(u => u.AuthoredPosts);
?????? Relationship(p => p.Comments).FromProperty(c => c.Post);
?????? Relationship(p => p.Poster).FromProperty(p => p.PostedPosts);
?????? //BlogID is a FK property and Blog is a navigation property backed by this FK????
?????? Relationship(p => p.Blog).FromProperty(b => b.Posts).HasConstraint((p, b) => p.BlogID == b.ID);
??
public class PersonConfiguration : EntityConfiguration
?? public PersonConfiguration()
??
?????? Property(p => p.ID).IsIdentity();
?????? Property(p => p.Firstname).HasMaxLength(100);
?????? Property(p => p.Surname).HasMaxLength(100);
?????? Property(p => p.EmailAddress).HasMaxLength(200);
?????? MapHierarchy(
?????????? p => new
??????????
?????????????? pid = p.ID,
?????????????? email = p.EmailAddress,
?????????????? fn = p.Firstname,
?????????????? ln = p.Surname,
??????????
?????? ).ToTable("People");
??
public class UserConfiguration : EntityConfiguration
?? public UserConfiguration()
??
?????? Property(u => u.Password).HasMaxLength(15).IsRequired();
?????? Relationship(u => u.AuthoredPosts).FromProperty(p => p.Author);
?????? Relationship(u => u.PostedPosts).FromProperty(p => p.Poster);
?????? MapHierarchy(
?????????? u => EntityMap.Row(
?????????????? EntityMap.Column(u.ID, " u i d"),
?????????????? EntityMap.Column(u.Password)
?????????????? )
?????? ).ToTable("Users");
??
5. 在 AdoEF_PocoExampleClient 的 Program.cs 中,加入下列的程序:
class Program
?? static void Main(string[] args)
??
?????? BlogDemo.Run();
??
6. 若你所使用的数据库是 SQL Server (非 Express 或 Compact Edition),可将 SQL Profiler 先启动并进入监听模式。
7. 按 F5 以调试器执行或按 CTRL+F5 直接执行,正常情况下窗口会出现以后消失。此时请打开 SQL Server Management Studio 并连到本机服务器中,即可以看到新的 Blogs 数据库。
8. 若在前面有启动 SQL Profiler 监听,则可以将它停止后,看看 Entity Framework 做了什么事:
如何,是不是有想要尖叫的感觉呢?有了这样的机制,Entity Framework 更向成熟的 ORM Framework 迈进一大步了。
由于这个功能太大,一回文章介绍不完,因此笔者下回再继续深入介绍这个神奇的功能。
参考数据:
Updated Feature CTP Walkthrough: Code Only for Entity Framework
http://blogs.msdn.com/adonet/archive/2009/11/12/updated-feature-ctp-walkthrough-code-only-for-entity-framework.aspx
范例程序下载:
http://blogs.msdn.com/adonet/attachment/9921786.ashx
原文:大专栏 [VS2010] ADO.NET Entity Framework 新功能:永续保存无知对象 (Persistence-Ignorant Object) Overview
以上是关于[VS2010] ADO.NET Entity Framework 新功能:永续保存无知对象 (Persistence-Ignorant Object) Overview的主要内容,如果未能解决你的问题,请参考以下文章
ADO.NET Entity Framework 如何查看T
如何从 ADO.NET Entity Framework 中的模型生成表?
我的VS2010中找不到ado.net实体数据模型,谁能帮忙解决一下