EF代码优先Code First
天方 人气:0CodeFirst是EntityFramework 4.1后新增的一种映射方式,在这种方式下,开发人员只需要编写代码,由ORM框架自动动创建模型和数据库,数据库则可看作类似于XML一样序列化的方式,非常简洁(由于开发人员可以无需关心数据库的具体结构,最初也有叫做CodeOnly的)。
下面就以一个简单的例子演示一下如何使用CodeFirst。
一、用Nuget添加EntityFramework框架的引用。
二、编写代码
static void Main(string[] args) { using (var db = new BloggingContext()) { // Create and save a new Blog Console.Write("Enter a name for a new Blog: "); var name = Console.ReadLine(); if (!string.IsNullOrEmpty(name)) { var blog = new Blog { Name = name }; db.Blogs.Add(blog); db.SaveChanges(); } // Display all Blogs from the database var query = from b in db.Blogs orderby b.Name select b; Console.WriteLine("All blogs in the database:"); foreach (var item in query) { Console.WriteLine(item.Name); } Console.WriteLine("Press any key to exit..."); } } public class Blog { public int BlogId { get; set; } public string Name { get; set; } } public class BloggingContext : DbContext { public DbSet<Blog> Blogs { get; set; } }
这里和以前的一点区别就是增加了一个继承自DbContext的BloggingContext对象,它表示数据库对象,Blogs则是它的表。如果不关心数据库的存储方式大可以把它看作一个全局变量。
上述代码是可以直接执行的,虽然这里没有主动指定数据库,但程序默认使用LocalDb或SqlExpress创建库,因为我用的是VS2012,就使用了LocalDb创建了库,并且生成的表的结构如下:
如下是CodeFirst映射数据库的一些基本原则:
数据库名:当没有显示设置数据连接的时候,默认的数据库是:.\SQLEXPRESS。如果本地没有SQLEXPRESS,EF会尝试LocalDb ((localdb)\v11.0) .\SQLEXPRESS 这个数据库包含在VS2012中。数据库的名称一般是DbContext的"命名空间.类名"
表名:表名默认为模型类名的复数形式,并且每个表都使用dbo构架创建。这里生成的就是dbo.Lodgings.
主键:Code First会默认将以类似Id结尾来命名的属性当作主键,如ID,Id,本例中的DestinationId都自动设置为主键。如果该属性是int类型,Code First会在数据库中默认将该列设置为自增长。
数据类型:在SQL Server中,字符串默认映射成nvarchar(max),byte[]映射成varbinary(max),bool映射成bit,decimal映射成decimal(18, 2),float映射成float。同时因为bool,decimal,float等是值类型,不能为给他们分配Null值。所生成的数据库会要求对应的列非空。如Lodgings表中的IsResort
外键:当CodeFirst检测到一对多的映射时,会自动生成相应的外键关联,这个下一节再介绍。
三、数据模型变化的处理
当我们的数据结构变化了后,就会出现数据模型和数据库不一致的情况。此时运行则会出现如下异常:
未经处理的异常: System.InvalidOperationException: The model backing the 'BloggingContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
官方给的解决方案如下:Code First Migrations。不过,在开发过程中,由于数据结构变更是很常见的事情,按照这个方案来未免麻烦了点,很多时候我们是采用一种更加简单粗暴的做法:
System.Data.Entity.Database.SetInitializer(new DropCreateDatabaseIfModelChanges());
把这句话放在程序的最开始。这样,一旦检测到数据库有变更,则会重建整个数据库。需要注意的时,由于重建数据库会删除所有的数据,过于霸气。因此不要轻易用于正式版本,使用时最好用DEBUG的宏把它括起来。
四、部署到其它数据库
虽然默认情况下会使用LocalDb或SqlExpress创建数据库非常方便,但实际应用中往往会要把它部署到指定的数据库中的,要指定数据库也非常简单,只需要在app.config中添加配置即可(原来产生的默认配置不用处理)。
<connectionStrings> <add name="BloggingContext" providerName="System.Data.SqlClient" connectionString="Server=.\SQLEXPRESS;Database=Products;Trusted_Connection=true;"/> </connectionStrings>
这里一并给一个比较常用的MySql连接的示例:
<connectionStrings> <add name="BloggingContext" providerName="MySql.Data.MySqlClient" connectionString="server=192.168.10.10;User Id=admin;password=test;database=BloggingContext;" /> </connectionStrings>
需要注意的是,如果原来的数据库存在的时候,往往会因为残留的数据和自动映射的不一致而出现无法创建表或其它的异常,最好先把原有的数据库给删掉。
加载全部内容