zoukankan      html  css  js  c++  java
  • 转:【工欲善其事必先利其器】—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元素,如下:

       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=(localdb)v11.0; Integrated Security=True; MultipleActiveResultSets=True" />
      11:       </parameters>
      12:     </defaultConnectionFactory>
      13:   </entityFramework>
      14: </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的情况下,代码中的优先。

    下面,写一个简单的控制台程序。代码如下:

       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 DbSet<Blog> Blogs { get; set; }
      39:         public DbSet<Post> Posts { get; set; }
      40:     }
      41:  
      42:     public class Blog
      43:     {
      44:         public Blog()
      45:         {
      46:             Posts = new List<Post>();
      47:         }
      48:  
      49:         public int Id { get; set; }
      50:         public string Name { get; set; }
      51:         public virtual List<Post> Posts { 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,如下图所示:

    QQ截图20121102235458

    重写上面配置有以下方法:

    1.在配置文件中添加connectionStrings,name和上下文类名一致。

       1: <connectionStrings>
       2:   <add name="TestContext1" connectionString="Data Source=(localdb)v11.0;Database=Test;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"/>
       3: </connectionStrings>

    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: <connectionStrings>
       2:   <add name="TestContext" connectionString="Data Source=.;Database=Test;User=sa;Password=sasa;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"/>
       3: </connectionStrings>

    2.连接Sql Server Compact 4.0

       1: <connectionStrings>
       2:   <add name="TestContext" connectionString="Data Source=|DataDirectory|Test.sdf" providerName="System.Data.SqlServerCe.4.0"/>
       3: </connectionStrings>

    3.连接MySql 5.5

    连接MySql数据库需要安装mysql提供程序mysql-connector-net-6.6.4,本文最后提供这些工具的下载地址。

       1: <connectionStrings>
       2:   <add name="TestContext"
       3:     connectionString="User Id=root;server=localhost;password=sasa;database=test1"
       4:     providerName="MySql.Data.MySqlClient" />
       5: </connectionStrings>

    三、数据库初始化

    1.关闭初始化

       1: Database.SetInitializer<TestContext>(null);

    2.CreateDatabaseIfNotExists

    这是Entity Framework的默认初始化策略,没有必要设置它,如果真的需要设置,如下:

       1: Database.SetInitializer(new CreateDatabaseIfNotExists<TestContext>());

    3.DropCreateDatabaseWhenModelChanges

    如果模型发生了改变,则删除并重建数据库。

       1: Database.SetInitializer(new DropCreateDatabaseWhenModelChanges<TestContext>());

    4.DropCreateDatabaseAlways

    无论模型和数据库匹配与否,都删除并重建数据库。

       1: Database.SetInitializer(new DropCreateDatabaseAlways<TestContext>());

    5.Database.Initialize可以强制初始化,即使在当前AppDomain中已经发生了。下面我写个单元测试程序,来演示这一点:

       1: [TestClass]
       2: public class UnitTest1
       3: {
       4:     [TestMethod]
       5:     public void TestForceInitialize()
       6:     {
       7:         //说明一点:我Demo中的TestContext和Microsoft.VisualStudio.TestTools.UnitTesting.TestContext冲突了,所以写成了ConnectDatabase.TestContext
       8:         //Arrage
       9:         Database.SetInitializer(new DropCreateDatabaseAlways<ConnectDatabase.TestContext>());
      10:         //Act
      11:         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:         //Assert
      36:         Assert.IsNotNull(blog);
      37:         Assert.AreEqual("强制初始化2", blog.Name);
      38:  
      39:     }
      40: }

    测试结果:

    QQ截图20121103225808

    因为设置的初始化策略为DropCreateDatabaseAlways,每一次调用Database.Initialize,参数为true,都会重新删除并创建数据库。

    四、Seed数据

    创建数据库时初始化一些数据,首先自定义初始化策略,重写Seed方法,代码如下:

       1: public class DropCreateDatabaseWithSeedData : DropCreateDatabaseAlways<TestContext>
       2: {
       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:     List<ConnectDatabase.Blog> blogList = 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: }

    测试结果:

    QQ截图20121103232156

    五、创建索引

    在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相关工具下载地址:

    1.mysql-5.5.28-winx64.msi

    2.mysql-connector-net-6.6.4.msi

    3.mysql-workbench-gpl-5.2.44-win32.msi

    本篇中主要讲了Entity Framework连接数据库、初始化的一些知识,跟题目”工欲善其事必先利其器“有点不符,但仔细想想也相差不了多远,解决了最基本的,后面的才能更顺利。

    系列的其他文章。

    如果遇到问题,可以访问Entity Framework社区,网址是www.ef-community.com

    转:http://www.cnblogs.com/nianming/archive/2012/11/04/2753183.html

  • 相关阅读:
    模版
    列表项模版
    vue eventBus 跳坑的办法
    vue适配移动端px自动转化为rem
    pc端,移动端css重置样式
    vue全局引入scss文件(推荐)
    vue安装scss,并且全局引入
    mapState
    通俗易懂的vuex-demo
    ve2.0 v-for循环报错的解决方案
  • 原文地址:https://www.cnblogs.com/superfeeling/p/5220115.html
Copyright © 2011-2022 走看看