微软推出ADO.NET Entity Framework,即下一代的ADO.NET。它是比Linq To SQL更加强大的ORM,让开发人员只需要着眼于领域对象模型的开发,而不需要考虑它们是如何与关系数据库交互。也就是说用entity开发非常迅猛,又比Linq to sql 在结构方面完善许多。
软件开发是一个迭代增量的过程,没有人能够一开始就完全设计好数据模型,因此对于Code First来说,最常见的开发场景是随着功能需求不断完善我们的数据模型。下面开始一步一步尝试数据库迁徙功能。在示例中我用Asp.net MVC3项目,首先新建一个项目,选择空模板,默认情况会引用一个EntityFramework,但很可能是4.1版本,删除这个引用,我们用NuGet将4.3版本的EF引入MVC3中: 当然你也可以通过命令行的方式(打开NuGet的Package Management Console,PMC):PM> Install-package EntityFramework假设我们要建立的是一个网上书店,首先我们通过Code First建立我们的模型:
public class BookContext : DbContext { public DbSet<Book> Books { get; set; } } public class Book { public int BookId { get; set; } public string Title { get; set; } public double Price { get; set; } }
非常简单的模型,下一步是在我们网站上使用这个模型,将书以列表的方式显示出来,第一步添加HomeController:
public class HomeController : Controller { public ActionResult Index() { BookContext db = new BookContext(); db.Books.Add(new Book { Title = "Think in C++", Price = 59 }); db.SaveChanges(); return View(db.Books.ToList()); } }
第二步添加对应的View:
@model List<MigarationDemo.Models.Book> @{ ViewBag.Title = "网上书店"; } <h2>书店里面有以下书籍</h2> <ul> @{ foreach (var item in Model) { <li>书名: @item.Title</li> } } </ul>
然后F5,你就应该在浏览器里面看到:
" 书店里面有一下书籍
书名:think in c++"
我们什么也没干,一个简单的网站就完成了,是不是很神奇?我们甚至没有配置数据库连接字符串。这都是因为EF设计的原则是“约定好于配置”
(Convention Over
Configuration),默认情况下,EF找你本机上的SqlExpress数据库,因为我机器上有这个数据库,所以EF就能自动连接数据库,然后根据上面的数据模型生成对应的数据库:
如果到这里,一切都正常,让我们进入正题,使用EF4.3中的Migaration功能:
第一步:修改我们的模型,由于新的需求,每本书还应该有一个ISBN编号:
public class Book { public int BookId { get; set; } public string Title { get; set; } public double Price { get; set; } public string ISBN { get; set; } }
如果这时候,你按F5,运行系统,会出现非法操作异常:“The model backing the 'BookContext' context has changed since the database was created. Consider using Code First Migrations to update the database .” 提示我们,应该进行数据库迁移。
很简单,只需要在PMC中执行下面3个命令:
1. Enable-Migrations
2. Add-Migration Book-ISBN (Book-ISBN是任意一个名称标记,用来标记一个迁移点)
3. Update-Database
如果执行完上面三个命令,并且一切顺利,恭喜你,数据库升级完成,你应该在项目里面看到:
并且数据库已经变成:
这时候F5,运行系统,应该一切正常了,你可以尝试在Controller中加入另外一条记录,我加入了:
db.Books.Add(new Book { Title = "Think in C++ Volumne Two: Practical Programming", Price = 59, ISBN = "978-7-111-17115-7" });
因此看到的是:
到此为止,我们已经一步一步完成了最简单的数据库迁徙/升级, 在上面生成的Migarations文件夹中主要一个配置文件和一个数据库迁移文件,数据库迁移文件有两个函数,一个是Up,即升级数据库,一个事Down,即回溯数据库,去看看生成的代码很容易理解它干了什么。
2.3 自定义数据库变更规则
虽然EF能够自动根据数据模型生成对应的数据库结构,但是通常自动生成的数据库只是最基本的,通常我们需要设置更多的属性。比如上面的Book数据模型,默认的数据库是以BookId这个主键建立索引,可是我们还希望以Title建立索引,这样我们能够快速的根据书名查找。另外,上面示例中,添加ISBN字段后,已经有了的数据默认是Null,这会在程序中引起不必要的麻烦,我们假设希望已有的记录的ISBN是000-0-000-00000-0。
面对上面这些需求,我们首先通过下面命令新建一个迁徙:
Add-Migration IndexTitleAndDefault
在项目树的Migrations文件夹下面会生成一个新的cs文件,我的是201202191349250_IndexTitleAndDefault.cs,注意前面时间戳会不一样。
然后修改生成的迁移文件:
public partial class IndexTitleAndDefault : DbMigration { public override void Up() { AlterColumn("Books", "Title", c => c.String(nullable: false,maxLength:100)); CreateIndex("Books", "Title", true,"Index_Title"); AlterColumn("Books", "ISBN", c => c.String(nullable: false, defaultValue: "000-0-000-00000-0")); } public override void Down() { DropIndex("Books", "Index_Title"); } }
最后执行命令:Update-Database,数据库应该建立了Title的索引,并且ISBN的默认值是000-0-000-00000-0。
2.5 版本回溯和Sql脚本生成
上面所有操作都是更新到最新的版本,但有时候我们希望数据库能回溯到以前的版本,这在以前手动维护数据库时候是比较困难的,而EF4.3提供的数据库变迁特性能很方便的进行回溯:
只需要执行Updat-Database命令的时候,加入–TargetMigration:"XXX" 参数即可,比如我们想回到第二步的版本,我们只需要执行:
PM> Update-Database –TargetMigration:"201202190625099_Book-ISBN"
但是为了实现版本回溯,我们就得特别注意实现Down函数,相当于Down函数式Up函数的反函数。
另外执行Update-Database命令的时候加入-Script参数,这样就不是直接修改数据库结构,而是生成相应的Sql脚本:
Update-Database -Script -SourceMigration:"aaa" -TargetMigration:"bbb"
如果不指定TargetMigration,就默认是迁徙到最新的版本。
3. 展望EF5
据微软的开发团队透露,EF的下一个版本是EF5,微软的版本号非常混乱,最开始EF是1.0,后来说要和.Net Framwork的版本号统一,所以直接就上到了EF4,现在.Net Framework的下一个版本是4.5,可是EF又要变成5了,他们在搞什么? 不管怎么样,看这个势头,EF5还是很值得期待的,有可能有以下改进:
1. 支持枚举类型
2. 性能将有很大提升
3. 改进SQL语句的生成,目前EF生成的Sql语句会比较复杂,在下一版本中将可能改善。
如果你希望EF有什么功能,可以去他们的网站投票,虽然最后决定权在微软Guy,但是你的一票可能会影响他们选择先开发什么功能。
4. 总结
现在看来,EF正在成为一个优秀的ORM框架,将能极大的提高程序员的开发效率,能够将程序员从数据访问层解脱出来,专注于业务逻辑层。当然,要掌握好EF,需要更加深入的学习,比如应该了解它都有哪些约定,应该了解一下它为我们生成的Sql语句,这样有助于我们写出高效的代码。
50cms 是采用entity技术的aspx cms系统