转:【工欲善其事必先利其器】—Entity Framework实例详解
开始本篇文章之前,先说一下Entity Framework 6 Alpha1在NuGet中已可用,原文链接http://blogs.msdn.com/b/adonet/archive/2012/10/30/ef6-alpha-1-available-on-nuget.aspx
俗话说:“工欲善其事必先利其器”,在深入讲解Entity Framework之前,先准备一下开发工具以及前期的配置。
一、开发工具
开发工具基本略过,这里说一下,我使用的是Visual Studio 2012,Entity Framework版本为4.3.1,获取这个版本的办法:在Package Manager Console中输入Install-Package EntityFramework -Version 4.3.1。至于数据库,主要是LocalDb。
二、连接数据库
当使用NuGet安装完Entity Framework后,在配置文件中会自动加入entityFramework节,里面有defaultConnectionFactory元素,如下:
: <?xml version="1.0" encoding="utf-8"?>
: <configuration>
: <configSections>
: <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
: <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
: </configSections>
: <entityFramework>
: <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
: <parameters>
: <parameter value="Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True" />
: </parameters>
: </defaultConnectionFactory>
: </entityFramework>
: </configuration>
在没有提供具体数据库连接的情况下,EF默认使用这一配置。如上面代码中,默认会连接到LocalDb,数据库的名称为上下文完全限定名(命名空间+类名)。以前经常提到默认连接到.\SQLEXPRESS,因为安装的版本不同。
EF中提供了两个连接工厂:SqlConnectionFactory和SqlCeConnectionFactory。使用方式分别如下:
1: Database.DefaultConnectionFactory = new SqlConnectionFactory("Data Source=.;Database=Test;UId=sa;Pwd=sasa;MultipleActiveResultSets=True");
或
1: Database.DefaultConnectionFactory = new SqlConnectionFactory("Data Source=.;Database=Test;User=sa;Password=sasa;MultipleActiveResultSets=True");
和
1: Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
在配置文件和代码中同时有DefaultConnectionFactory的情况下,代码中的优先。
下面,写一个简单的控制台程序。代码如下:
: namespace ConnectDatabase
: {
: class Program
: {
: static void Main(string[] args)
: {
: using (TestContext ctx = new TestContext())
: {
: var blog = new Blog()
: {
: Name = "EF"
: };
: blog.Posts.Add(new Post()
: {
: Title = "连接数据库",
: Content = "这是连接数据库的测试",
: Creationdate = DateTime.Now,
: Blog = blog
: });
: ctx.Blogs.Add(blog);
: ctx.SaveChanges();
:
: foreach (var item in ctx.Blogs)
: {
: Console.WriteLine(item.Name);
: }
: }
: }
: }
:
: public class TestContext : DbContext
: {
: protected override void OnModelCreating(DbModelBuilder modelBuilder)
: {
: base.OnModelCreating(modelBuilder);
: }
:
: public DbSet<Blog> Blogs { get; set; }
: public DbSet<Post> Posts { get; set; }
: }
:
: public class Blog
: {
: public Blog()
: {
: Posts = new List<Post>();
: }
:
: public int Id { get; set; }
: public string Name { get; set; }
: public virtual List<Post> Posts { get; set; }
: }
:
: public class Post
: {
: public int Id { get; set; }
: public string Title { get; set; }
: public string Content { get; set; }
: public DateTime Creationdate { get; set; }
: public virtual Blog Blog { get; set; }
: }
: }
使用默认连接配置,生成的数据库名称为:ConnectDatabase.TestContext,如下图所示:

重写上面配置有以下方法:
1.在配置文件中添加connectionStrings,name和上下文类名一致。
: <connectionStrings>
: <add name="TestContext1" connectionString="Data Source=(localdb)\v11.0;Database=Test;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"/>
: </connectionStrings>
2.同1,但是name和上下文类名不一致。这就需要修改TextContext代码,如下:
: public TestContext() : this("TestContext1") { }
:
: public TestContext(string nameOrConnectionString)
: : base(nameOrConnectionString)
: {
:
: }
或
: public TestContext()
: : base("name=TestContext1")
: {
:
: }
或
: public TestContext():base("TestContext1"){}
下面给出连接具体数据库的配置:
1.连接Sql Server数据库
: <connectionStrings>
: <add name="TestContext" connectionString="Data Source=.;Database=Test;User=sa;Password=sasa;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"/>
: </connectionStrings>
2.连接Sql Server Compact 4.0
: <connectionStrings>
: <add name="TestContext" connectionString="Data Source=|DataDirectory|\Test.sdf" providerName="System.Data.SqlServerCe.4.0"/>
: </connectionStrings>
3.连接MySql 5.5
连接MySql数据库需要安装mysql提供程序mysql-connector-net-6.6.4,本文最后提供这些工具的下载地址。
: <connectionStrings>
: <add name="TestContext"
: connectionString="User Id=root;server=localhost;password=sasa;database=test1"
: providerName="MySql.Data.MySqlClient" />
: </connectionStrings>
三、数据库初始化
1.关闭初始化
: Database.SetInitializer<TestContext>(null);
2.CreateDatabaseIfNotExists
这是Entity Framework的默认初始化策略,没有必要设置它,如果真的需要设置,如下:
: Database.SetInitializer(new CreateDatabaseIfNotExists<TestContext>());
3.DropCreateDatabaseWhenModelChanges
如果模型发生了改变,则删除并重建数据库。
: Database.SetInitializer(new DropCreateDatabaseWhenModelChanges<TestContext>());
4.DropCreateDatabaseAlways
无论模型和数据库匹配与否,都删除并重建数据库。
: Database.SetInitializer(new DropCreateDatabaseAlways<TestContext>());
5.Database.Initialize可以强制初始化,即使在当前AppDomain中已经发生了。下面我写个单元测试程序,来演示这一点:
: [TestClass]
: public class UnitTest1
: {
: [TestMethod]
: public void TestForceInitialize()
: {
: //说明一点:我Demo中的TestContext和Microsoft.VisualStudio.TestTools.UnitTesting.TestContext冲突了,所以写成了ConnectDatabase.TestContext
: //Arrage
: Database.SetInitializer(new DropCreateDatabaseAlways<ConnectDatabase.TestContext>());
: //Act
: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())
: {
: ctx.Database.Initialize(force: true);
: ctx.Blogs.Add(new ConnectDatabase.Blog()
: {
: Name = "强制初始化1"
: });
: ctx.SaveChanges();
: }
: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())
: {
: ctx.Database.Initialize(force: true);
: ctx.Blogs.Add(new ConnectDatabase.Blog()
: {
: Name = "强制初始化2"
: });
: ctx.SaveChanges();
: }
: ConnectDatabase.Blog blog = null;
: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())
: {
: blog = ctx.Blogs.FirstOrDefault();
: }
:
: //Assert
: Assert.IsNotNull(blog);
: Assert.AreEqual("强制初始化2", blog.Name);
:
: }
: }
测试结果:

因为设置的初始化策略为DropCreateDatabaseAlways,每一次调用Database.Initialize,参数为true,都会重新删除并创建数据库。
四、Seed数据
创建数据库时初始化一些数据,首先自定义初始化策略,重写Seed方法,代码如下:
: public class DropCreateDatabaseWithSeedData : DropCreateDatabaseAlways<TestContext>
: {
: protected override void Seed(TestContext context)
: {
: context.Blogs.Add(new Blog()
: {
: Name = "种子数据1"
: });
: context.Blogs.Add(new Blog()
: {
: Name = "种子数据2"
: });
: //注意没有调用context.SaveChanges(),base.Seed(context)会调用
: base.Seed(context);
: }
: }
下面是测试程序:
: [TestMethod]
: public void SeedData()
: {
: Database.SetInitializer(new DropCreateDatabaseWithSeedData());
: List<ConnectDatabase.Blog> blogList = null;
: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())
: {
: blogList = ctx.Blogs.OrderBy(t => t.Id).ToList();
: }
: Assert.AreEqual(, blogList.Count);
: Assert.AreEqual("种子数据1", blogList[].Name);
: Assert.AreEqual("种子数据2", blogList[].Name);
: }
测试结果:

五、创建索引
在Seed方法中,使用ExecuteSqlCommand创建索引,代码如下:
: protected override void Seed(TestContext context)
: {
: context.Database.ExecuteSqlCommand("CREATE INDEX IX_Test_Name ON Blogs (Name)");
: context.Blogs.Add(new Blog()
: {
: Name = "种子数据1"
: });
: context.Blogs.Add(new Blog()
: {
: Name = "种子数据2"
: });
: //注意没有调用context.SaveChanges(),base.Seed(context)会调用
: base.Seed(context);
: }
六、结束语
mysql相关工具下载地址:
2.mysql-connector-net-6.6.4.msi
3.mysql-workbench-gpl-5.2.44-win32.msi
本篇中主要讲了Entity Framework连接数据库、初始化的一些知识,跟题目”工欲善其事必先利其器“有点不符,但仔细想想也相差不了多远,解决了最基本的,后面的才能更顺利。
点击查看《Entity Framework实例详解》系列的其他文章。
如果遇到问题,可以访问Entity Framework社区,网址是www.ef-community.com
转:http://www.cnblogs.com/nianming/archive/2012/11/04/2753183.html
转:【工欲善其事必先利其器】—Entity Framework实例详解的更多相关文章
- Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- 【配置属性】—Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- —Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- 【迁移】—Entity Framework实例详解 转
一.Entity Framework 迁移命令(get-help EntityFramework) Enable-Migrations 启用迁移 Add-Migration 为挂起的Model变化添加 ...
- 【迁移】—Entity Framework实例详解
好久没有在博客园更新博客了,如今都换了新公司.前段时间写了关于EF迁移的文档,今天拿出来作为这个系列的一篇吧. 一.Entity Framework 迁移命令(get-help EntityFrame ...
- 【配置关系】—Entity Framework实例详解
实体间的关系,简单来说无非就是一对一.一对多.多对多,根据方向性来说又分为双向和单向.Code First在实体关系上有以下约定: 1. 两个实体,如果一个实体包含一个引用属性,另一个实体包含一个集合 ...
- [转]C#综合揭秘——Entity Framework 并发处理详解
本文转自:http://www.cnblogs.com/leslies2/archive/2012/07/30/2608784.html 引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的 ...
- Linq实战 之 Linq to Sql及Entity Framework操作详解
Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity f ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...
随机推荐
- Unity Built-in Shader详解二
这次主要讨论Unity自带的Shader中Transparent Shader Family 这个家族的Shader一共7种,原理和类型与Normal中的上差不多,只不过这些Shader是用在半透明或 ...
- 移动端JS 触摸事件基础
一.手机上的触摸事件 基本事件: touchstart //手指刚接触屏幕时触发 touchmove //手指在屏幕上移动时触发 touchend //手指从屏幕上移开时触发 ...
- POJ 3411 Paid Roads(DFS)
题目链接 点和边 都很少,确定一个界限,爆搜即可.判断点到达注意一下,如果之前已经到了,就不用回溯了,如果之前没到过,要回溯. #include <cstring> #include &l ...
- Web前端开发规范文档你需要知道的事--HTML、css、js、文档等需要规范内容
规范目的 为提高团队协作效率,便于后台人员添加功能及前端后期优化维护,输出高质量的文档,特制订此文档.本规范文档一经确认,前端开发人员必须按本文档规范进行前台页面开发.本文档如有不对或者不 ...
- Java 反射机制学习资料
Java反射——引言 Java反射——Class对象 Java反射——构造函数 Java反射——字段 Java反射——方法 Java反射——Getter和Setter Java反射——私有字段和私有方 ...
- 8.按要求编写Java应用程序。 (1)建立一个名叫Cat的类: 属性:姓名、毛色、年龄 行为:显示姓名、喊叫 (2)编写主类: 创建一个对象猫,姓名为“妮妮”,毛色为“灰色”,年龄为2岁,在屏幕上输 出该对象的毛色和年龄,让该对象调用显示姓名和喊叫两个方法。
package liu0917; public class Cat { String name="妮妮"; int age=2; String maose="灰色&quo ...
- 简单查看tomcat中部署java服务的内存使用情况
vim tomcat_mem.sh NAME=$1 #部署项目名称 #PID=`ps -ef|grep tomcat|grep $NAME|awk '{print $2}'` PID=`ps -ef| ...
- 使用本函式处理后的字串会沿续到PHP程式而转入eval函数
html码放在数据库里,通过php文件调用,经过一系列处理后,用eval函数 将希望的变量带入生成所需要的动态页.这样,我就没再看vbb源码,而转入eval函数了. 星空浪子的php中文手册是这样介绍 ...
- [转]用Linq取CheckBoxList選取項目的值
本文转自:http://www.dotblogs.com.tw/hatelove/archive/2011/11/17/linq-checkboxlist-items-selected-values. ...
- sql 语句大小写的问题
关键字不区分大小写 例如 select ,from, 大小写均可 标识符区分大小写 例如 表名,列名 标识符如果不加双引号,默认是按大写执行 标识符如果加双引号,则是按原始大小写执行 但是,当表名加上 ...