EntityFramework连接数据库、初始化的一些知识
- 时间:2015年04月02日 15:28:36 来源:魔法猪系统重装大师官网 人气:3471
俗话说:“工欲善其事必先利其器”,在深入讲解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元素,如下:
1: <?xml version="1.0" encoding="utf-8"?>
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
在没有提供具体数据库连接的情况下,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的情况下,代码中的优先。
下面,写一个简单的控制台程序。代码如下:
1: namespace ConnectDatabase
2: {
3: class Program
4: {
5: static void Main(string[] args)
6: {
7: using (TestContext ctx = new TestContext())
8: {
9: var blog = new Blog()
10: {
11: Name = "EF"
12: };
13: blog.Posts.Add(new Post()
14: {
15: Title = "连接数据库",
16: Content = "这是连接数据库的测试",
17: Creationdate = DateTime.Now,
18: Blog = blog
19: });
20: ctx.Blogs.Add(blog);
21: ctx.SaveChanges();
22:
23: foreach (var item in ctx.Blogs)
24: {
25: Console.WriteLine(item.Name);
26: }
27: }
28: }
29: }
30:
31: public class TestContext : DbContext
32: {
33: protected override void OnModelCreating(DbModelBuilder modelBuilder)
34: {
35: base.OnModelCreating(modelBuilder);
36: }
37:
38: public DbSetBlogs { get; set; }
39: public DbSetPosts { get; set; }
40: }
41:
42: public class Blog
43: {
44: public Blog()
45: {
46: Posts = new List();
47: }
48:
49: public int Id { get; set; }
50: public string Name { get; set; }
51: public virtual ListPosts { get; set; }
52: }
53:
54: public class Post
55: {
56: public int Id { get; set; }
57: public string Title { get; set; }
58: public string Content { get; set; }
59: public DateTime Creationdate { get; set; }
60: public virtual Blog Blog { get; set; }
61: }
62: }
使用默认连接配置,生成的数据库名称为:ConnectDatabase.TestContext,如下图所示:
重写上面配置有以下方法:
1.在配置文件中添加connectionStrings,name和上下文类名一致。
1:
2:
3:
2.同1,但是name和上下文类名不一致。这就需要修改TextContext代码,如下:
1: public TestContext() : this("TestContext1") { }
2:
3: public TestContext(string nameOrConnectionString)
4: : base(nameOrConnectionString)
5: {
6:
7: }
或
1: public TestContext()
2: : base("name=TestContext1")
3: {
4:
5: }
或
1: public TestContext():base("TestContext1"){}
下面给出连接具体数据库的配置:
1.连接Sql Server数据库
1:
2:
3:
2.连接Sql Server Compact 4.0
1:
2:
3:
3.连接MySql 5.5
连接MySql数据库需要安装mysql提供程序mysql-connector-net-6.6.4,本文最后提供这些工具的下载地址。
1:
2: 3: connectionString="User Id=root;server=localhost;password=sasa;database=test1"4: providerName="MySql.Data.MySqlClient" />5:三、数据库初始化
1.关闭初始化
1: Database.SetInitializer(null); 2.CreateDatabaseIfNotExists
这是Entity Framework的默认初始化策略,没有必要设置它,如果真的需要设置,如下:
1: Database.SetInitializer(new CreateDatabaseIfNotExists()); 3.DropCreateDatabaseWhenModelChanges
如果模型发生了改变,则删除并重建数据库。
1: Database.SetInitializer(new CreateDatabaseIfNotExists()); 4.DropCreateDatabaseAlways
无论模型和数据库匹配与否,都删除并重建数据库。
1: Database.SetInitializer(new DropCreateDatabaseAlways()); 5.Database.Initialize可以强制初始化,即使在当前AppDomain中已经发生了。下面我写个单元测试程序,来演示这一点:
1: [TestClass]2: public class UnitTest13: {4: [TestMethod]5: public void TestForceInitialize()6: {7: //说明一点:我Demo中的TestContext和Microsoft.VisualStudio.TestTools.UnitTesting.TestContext冲突了,所以写成了ConnectDatabase.TestContext8: //Arrage9: Database.SetInitializer(new DropCreateDatabaseAlways()); 10: //Act11: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())12: {13: ctx.Database.Initialize(force: true);14: ctx.Blogs.Add(new ConnectDatabase.Blog()15: {16: Name = "强制初始化1"17: });18: ctx.SaveChanges();19: }20: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())21: {22: ctx.Database.Initialize(force: true);23: ctx.Blogs.Add(new ConnectDatabase.Blog()24: {25: Name = "强制初始化2"26: });27: ctx.SaveChanges();28: }29: ConnectDatabase.Blog blog = null;30: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())31: {32: blog = ctx.Blogs.FirstOrDefault();33: }34:35: //Assert36: Assert.IsNotNull(blog);37: Assert.AreEqual("强制初始化2", blog.Name);38:39: }40: }测试结果:
因为设置的初始化策略为DropCreateDatabaseAlways,每一次调用Database.Initialize,参数为true,都会重新删除并创建数据库。
四、Seed数据
创建数据库时初始化一些数据,首先自定义初始化策略,重写Seed方法,代码如下:
1: public class DropCreateDatabaseWithSeedData : DropCreateDatabaseAlways2: {3: protected override void Seed(TestContext context)4: {5: context.Blogs.Add(new Blog()6: {7: Name = "种子数据1"8: });9: context.Blogs.Add(new Blog()10: {11: Name = "种子数据2"12: });13: //注意没有调用context.SaveChanges(),base.Seed(context)会调用14: base.Seed(context);15: }16: }下面是测试程序:
1: [TestMethod]2: public void SeedData()3: {4: Database.SetInitializer(new DropCreateDatabaseWithSeedData());5: ListblogList = null; 6: using (ConnectDatabase.TestContext ctx = new ConnectDatabase.TestContext())7: {8: blogList = ctx.Blogs.OrderBy(t => t.Id).ToList();9: }10: Assert.AreEqual(2, blogList.Count);11: Assert.AreEqual("种子数据1", blogList[0].Name);12: Assert.AreEqual("种子数据2", blogList[1].Name);13: }测试结果:
五、创建索引
在Seed方法中,使用ExecuteSqlCommand创建索引,代码如下:
1: protected override void Seed(TestContext context)2: {3: context.Database.ExecuteSqlCommand("CREATE INDEX IX_Test_Name ON Blogs (Name)");4: context.Blogs.Add(new Blog()5: {6: Name = "种子数据1"7: });8: context.Blogs.Add(new Blog()9: {10: Name = "种子数据2"11: });12: //注意没有调用context.SaveChanges(),base.Seed(context)会调用13: base.Seed(context);14: }六、MySQL相关
mysql相关工具下载地址:
1.mysql-5.5.28-winx64.msi
2.mysql-connector-net-6.6.4.msi
3.mysql-workbench-gpl-5.2.44-win32.msi