EntityFramework CodeFirst 4.3 step by step (1)
自CodeFirst推出以来,一直以来都想去学一学用一用,苦于一直被各种事情所羁绊(当然这不是理由啦!)而delay。。。
最近跳槽到一家德资企业,进项目组后主要在做一个船舶信息管理和控制类的软件,客户是挪威佬。项目中就用到了codefirst4.2,真心觉得老外相当地与时俱进啊!!! 于是再也忍不住了,要来好好玩一玩CodeFirst,为了督促我自己学习,我向园子里的各位博友保证会将CodeFirst这个系列写完整,恳请大家监督和鞭策我吧,哈哈!
下面一段时间,我会带着如下几个问题去学习CodeFirst4.3:
1. What's the advantage of codefirst.
2. How to config and use.
3. How to migrate.
4. How to use in project.
下面正式开始我们的CodeFirst之旅:
1. What's the advantage of codefirst.
CodeFirst顾名思义是代码优先,它摈弃了传统的项目开发模式中诸如ER模型,DB设计等过程,让我们直接从DomainModel也就是领域模型开始开发。没有了数据库设计这个环节,我们程序员和领域专家在进行每一次沟通之后,都可以很快地抽象出领域模型,并实现相应的功能,然后我们再利用CodeFirst提供的功能反向生成数据库。
从这个过程我们可以看出CodeFirst有以下几点优势:
开发速度:我们程序员在此时暂时不需要具备DBA相关技能,直接上代码(程序员最喜欢的啦)。
代码清晰可控制:没有EntityFramework自动生成的Entity类,取而代之的是我们自己根据领域模型设计出的DomainModel。
和edmx model说再见:还记得edmx model吗?每次数据库有改动都要去维护这个东西,如果开发是大家连的是同一个数据库的话经常会出现数据库更新和edmx model更新不同步(这个我以前公司的兄弟们应该相当有体会哈)。
2. How to config and use.
配置和使用网上一搜到处都是,但几乎都只同一个版本,不知道是哪个在搞批发的,用的都是Sql Express,我们实际项目中Sql Server Instance很少有完整的demo。
废话不多说了,下面来讲讲CodeFirst4.3具体的配置和使用。
1. 添加EntityFramework4.3的引用,没有的话装一个NuGet就什么都有了。
2. System.ComponentModel.DataAnnotations,System.Data.Entity引用添加了吗?没有的话赶紧添加吧!
3. System.Data.SqlServerCe.Entity.dll这个程序集的引用肯定没有吧,是程序员不要说找不到哦,如果找不到直接email to me,我发你得了!
4. 上面这些reference都添加后,再来修改config文件(根据project的类型可以是app.config或者web.config)
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <configSections> 4 <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 5 <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 6 </configSections> 7 <!--<entityFramework> 8 <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> 9 <parameters> 10 <parameter value="Data Source=.\SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True" /> 11 </parameters> 12 </defaultConnectionFactory> 13 </entityFramework>--> 14 15 <connectionStrings> 16 <add name="BlogDB" connectionString="Data Source=.;Initial Catalog=BlogDB;User ID=sa;Password=123" providerName="System.Data.SqlClient" /> 17 </connectionStrings> 18 <system.data> 19 <DbProviderFactories> 20 <remove invariant="System.Data.SqlServerCe.4.0" /> 21 <add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" /> 22 </DbProviderFactories> 23 </system.data> 24 </configuration>
这个折腾了我一个多小时,不解释,照做准没错!
5. 配置OK,下面可以开始舒舒服服地写代码啦!
假设我们做一个 Blog系统,和领域专家讨论后抽象出一个DomainModel为Blog
1 class Blog 2 { 3 public int BlogId { get; set; } 4 public string Name { get; set; } 5 }
根据以前的经验,这个应该是数据库中的一张表,那么我们如何生成一张Blogs表呢?
我们需要一个继承自DbContext的类,并且有一个属性
1 class BlogContext : DbContext 2 { 3 public BlogContext() 4 : base("BlogDB") //the name shall be equal to the name of connectionstring in config file. 5 { 6 } 7 8 public DbSet<Blog> Blogs { get; set; } 9 }
我用的是一个控制台程序,那就在main函数里面进行一次数据库插入操作
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 using (var db = new BlogContext()) 6 { 7 db.Blogs.Add(new Blog { Name = "Another Blog " }); 8 db.SaveChanges(); 9 10 foreach (var blog in db.Blogs) 11 { 12 Console.WriteLine(blog.Name); 13 } 14 15 Console.ReadLine(); 16 } 17 } 18 }
打开数据库,BlogDB乖乖地在那里躺着了!
至此,我们已经算是尝试了一把CodeFirst,但问题来了,如果我加一个User类,难道非要进行一次数据库操作吗?
CodeFirst4.3当然不会这么弱了,它提供了强大的Migration功能来完成数据库的更新,从而让我们远离EntityFramework时代去维护edmx model的痛苦。同时也改变需求变更带来的数据库、代码同步更改的囧境。
下一节我们来讲Migration。