zoukankan      html  css  js  c++  java
  • C# ORM—Entity Framework 之Code first(代码优先)(二)

    一、Entity Framework Code first(代码优先)使用过程

      1.1Entity Framework 代码优先简介

        不得不提Entity Framework Code First这个介于牛A与牛C之间的功能,从4.1 开始的Code first使程序员,使软件开发流程进入一个更加方便快捷的时代。

        Code First是EntityFramework实现ORM的一种有利手段,因为传统编程方式都是先建立数据库,然后根据数据库模型为应用程序建模,再进行开发;CodeFirst代码优先,先在程序中建立要映射到数据库的实体结构,然后EntityFramework可以根据实体结构生成所对应的数据库。

       1.2 最新版本简介(Entity Framework 5,现在VS2012中已出现EF6.0.0beta1版本了)

        
        1.2.1 枚举支持是EF 久等的功能,并让您在您的域类中拥有枚举属性。EF5 让枚举支持在 EF 设计器和Code First中是可用的。
        1.2.2 现在,现有数据库中的表值函数可以包含在使用 EF 设计器所创建的模型中。
        1.2.3 可以使用DbGeography 和 DbGeometry 类型在模型中公开空间数据类型。空间数据可以包含在由EF 设计器或Code First所创建的模型中。
        1.2.4 EF5 还包括一些重大的性能改进,Entity Framework 5相比EF4在性能上会有67%的提升 。使用这个版本EF的应用程序之所以性能提升,要部分归功于LINQ to Entities查询的自动编译。自动编译功能一直都是EF框架中的一部分,只是需要开发人员调用CompiledQuery.Compile才能够使用。现在,EF 5会自动处理这步工作:当某个查询首次运行时,它会被编译并缓存,从而使得后续请求可以避免重新完全编译。EF 4为ESQL(嵌入式SQL)查询使用了编译后的查询缓存,而EF 5将该功能扩展到了LINQ to Entity查询中。一旦缓冲中超过800个编译后的查询,某个回收算法将开始生效并以每分钟一次的周期清理缓存。 实体依据LFRU(最近最早使用)原理从缓存中移除。

      1.3 Visual Studio 2012中的EF设计器,它也有一些新的功能:

        1.3.1 现在模型可以被分为多个关系图,在使用大型的模型时,这是很不错的。您还可以应用着色到实体中来帮助您识别您的模型的分区。
        1.3.2 改进了转置模型的向导,使其更容易和更快地为查询数据批量导入存储过程。

      1.4 参考文章、博文
        http://msdn.microsoft.com/zh-cn/magazine/jj991973.aspx
        
    http://msdn.microsoft.com/zh-cn/magazine/hh547106.aspx
        http://blogs.msdn.com/b/jason_zander/archive/2012/07/30/entity-framework-code-first-asp-net-web-api.aspx
        http://msdn.microsoft.com/zh-cn/magazine/hh126815.aspx

    二、 Code First New Database使用

        2.1 创建控制台项目

        2.2 添加引用最新的Entity Framework

          项目上右键单击—》管理NeGut程序包—》联机,找到EntityFramework—》安装
          安装之后即可看到packages.config

        2.3 建立实体类

     1     public class Blog
     2     {
     3         public int BlogId { get; set; }
     4         public string Name { get; set; }
     5 
     6         public virtual List<Post> Posts { get; set; }
     7     }
     8     public class Post
     9     {
    10         public int PostId { set; get; }
    11         public string Title { get; set; }
    12         public string Content { get; set; }
    13 
    14         public int BlogId { set; get; }
    15         public virtual Blog Blog { get; set; }
    16     }
    View Code

        2.4 建立数据上下文类

          添加引用:using System.Data.Entity;并继承DbContext

          代码示例:

    1     public class BlogContext : DbContext
    2     {
    3         public DbSet<Blog> Blogs { set; get; }
    4         public DbSet<Post> Posts { get; set; }
    5     }
    View Code

        2.5 编写测试代码

     1             using (var db = new BlogContext())
     2             {
     3                 Console.WriteLine("输入一个新的Blog名称");
     4                 var name = Console.ReadLine();
     5 
     6                 var blog = new Blog { Name = name };
     7                 db.Blogs.Add(blog);
     8                 db.SaveChanges();
     9 
    10                 var query = from b in db.Blogs
    11                             orderby b.Name
    12                             select b;
    13 
    14                 foreach (var item in query)
    15                 {
    16                     Console.WriteLine(item.Name);
    17                 }
    18             }
    19             Console.ReadKey();
    View Code

          以上便是最基本的应用

        2.6 查看数据库

          打开SQL Server对象资源管理器,一般数据库会建立在本机的打开数据库默认实例对象上

      2.7 使用扩展

          使用“程序包管理器控制台”查看、操作生成数据库模型:打开方式:工具—》库程序包管理器—》程序包管理器控制台(注意要选择成您要操作的项目)

          主要是数据库迁移(增加实体类(数据表)、增加实体类字段(数据库字段))

          具体使用(打开“程序包管理器控制台”):

            1. 输入命令:Enable-Migrations 启用Code first Migration;运行成功后会产生Migrations文件夹及两个类:Configuration.cs  和<timestamp>_InitialCreate.cs,这是一个用时间戳作为前缀的类。如201307080301469_InitialCreate.cs
              注:如果不小心删除了201307080301469_InitialCreate.cs这个文件,可以使用Enable-Migration -Force重新创建

              1.1 添加字段:如在Blog内增加Url

    1     public class Blog
    2     {
    3         public int BlogId { get; set; }
    4         public string Name { get; set; }
    5         public string Url { get; set; }
    6 
    7         public virtual List<Post> Posts { get; set; }
    8     }
    View Code

                输入命令:Add-Migration AddUrl,同时在Migrations下会有201307080524348_AddUrl.cs文件
                继续输入命令:Update-Database,更新数据库

              1.2 添加新的实体类文件User

    1     public class User
    2     {
    3         public string UserName { get; set; }
    4         public string DisplayName { get; set; }
    5     }

                 输入命令:Add-Migration AddUser;(注可能提示没有主键,此时要为表User建立主键,先添加引用:using System.ComponentModel.DataAnnotations;)

    1     public class User
    2     {
    3         [Key]
    4         public string UserName { get; set; }
    5         public string DisplayName { get; set; }
    6     }

                  再次执行:Add-Migration AddUser;在执行Update-Database,查看数据库管理工具数据库已建立

              1.3 修改字段

                修改User实体类中的DisplayName为“display_name”在数据上下文类BlogContext中添加以下代码:

    1     protected override void OnModelCreating(DbModelBuilder modelBuilder)
    2         {
    3             modelBuilder.Entity<User>()
    4                 .Property(u => u.DisplayName)
    5                 .HasColumnName("display_name");
    6         }

                输入命令:Add-Migration ChangeDisplayName  ,在执行Update-Database,即可

              1.4 删除某一个字段:删除Blog实体类中的Url

                首先在实体类中删除此字段

    1     public class Blog
    2     {
    3         public int BlogId { get; set; }
    4         public string Name { get; set; }
    5 
    6         public virtual List<Post> Posts { get; set; }
    7     }

                以上代码已删除。
                输入命令:Add-Migration DeleteUrl ,之后在执行Update-Database即可。。
       

    三、Code First An Existing Database使用(数据迁移功能暂时不能使用) 

      3.1 下载安装扩展插件

        工具—》扩展和更新—》联机,查找“Entity Framework Power Tools”,进行下载,安装,重新启动。查看是否安装成功,工具—》扩展和更新—》已安装,是否有此工具

      3.2 新建数据表Blogs

    1 CREATE TABLE [dbo].[Blogs] (
    2     [BlogId] INT            IDENTITY (1, 1) NOT NULL,
    3     [Name]   NVARCHAR (200) NULL,
    4     [Url] NVARCHAR(200) NULL, 
    5     CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
    6 );
    View Code

        以及新建数据表Posts

     1 CREATE TABLE [dbo].[Posts] (
     2     [PostId]  INT            IDENTITY (1, 1) NOT NULL,
     3     [Title]   NVARCHAR (MAX) NULL,
     4     [Content] NVARCHAR (MAX) NULL,
     5     [BlogId]  INT            NOT NULL,
     6     CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([PostId] ASC),
     7     CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE
     8 );
     9 
    10 
    11 GO
    12 CREATE NONCLUSTERED INDEX [IX_BlogId]
    13     ON [dbo].[Posts]([BlogId] ASC);
    View Code

      3.3 创建一个控制台项目(名称如:CodeFirstExistingDatabaseSample)

      3.4 在项目CodeFirstExistingDatabaseSample上右键单击—》菜单中会有“Entity Framework”选项—》选择Reverse Engineer Code First,输入相应的数据库地址,用户名、密码、要操作的数据库等信息,确定即可。(前提是要安装好Power Tools 插件)

      3.5 数据迁移,此功估计EF还暂未实现,从使用工具Entity Framework Power Tools Betas3 以及使用的Entity Framework 6.0.0-beta1来看,估计这是EF 6.0的功能 

    四、数据库生成位置可控制(其实主要就是DbContext的构造函数)

          1.使用DbContext的构造函数:public DbContext(string nameOrConnectionString)

            a、在app.config中添加:

    1   <connectionStrings>
    2     <add name="CodeFirstBlogContext" providerName="System.Data.SqlClient" connectionString="Server=.;Database=CodeFirstBlog;uid=sa;pwd=sa" />
    3   </connectionStrings>

            注:当然这里也可以添加使用其他数据库,但是要提起安装好驱动:引用可参考此文:http://www.cnblogs.com/yylp521/p/3173176.html

            b、在数据上下文类中添加构造函数(原来没有显示出现,调用默认的一般是本机.sqlexpress数据库实例)

    1         public BlogContext(string config)
    2             : base(config)
    3         {
    4         }

            这里可以显示的引用配置文件中的配置库,注:此处config可以直接写name=CodeFirstBlogContext,是配置文件中的connectionStrings下的name。

          2. 使用DbContext的构造函数:public DbContext(DbConnection existingConnection, bool contextOwnsConnection)

            a、在数据上下文类中添加构造函数(原来没有显示出现,调用默认的一般是本机.sqlexpress数据库实例)

    1 public BlogContext(DbConnection connection,bool contextOwnsConnection)
    2             : base(connection, contextOwnsConnection) 
    3         { }

            b、使用时建立一个Connection即可

     1             string connStr = "Server=.;Database=CodeFirstBlog2;uid=sa;pwd=sa";
     2             using (SqlConnection conn = new SqlConnection(connStr))
     3             {
     4                 using (var db = new BlogContext(conn, false))
     5                 {
     6                     Console.WriteLine("输入一个新的Blog名称");
     7                     var name = Console.ReadLine();
     8 
     9                     var blog = new Blog { Name = name };
    10                     db.Blogs.Add(blog);
    11                     db.SaveChanges();
    12 
    13                     var query = from b in db.Blogs
    14                                 orderby b.Name
    15                                 select b;
    16 
    17                     foreach (var item in query)
    18                     {
    19                         Console.WriteLine(item.Name);
    20                     }
    21                 }
    22             }
    23             Console.ReadKey();
    View Code

          3. 使用数据的连接工厂

    1             Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Server=.sqlexpress;Database=CodeFirstBlog4;uid=sa;pwd=sa");
    2             using (var db=new BlogContext())
    3             {
    4                 db.Database.Initialize(true);
    5                 db.Blogs.Add( new Blog { Name = "test" });
    6                 db.SaveChanges();
    7             }

           注:这里指定数据库名称无效,应该与Database的Initialize方法有关,待查证。

           4.这里还有其他的DbContext构造函数可用,可直接查看DbContext类的实现。    

  • 相关阅读:
    GC(垃圾分代收集)
    排序算法总结
    Redis中的数据结构
    事务的隔离性(续篇)
    手写Spring mvc框架 (二)
    MySql日志与事务的隔离级别
    手写Spring mvc框架 (一)
    IO流
    随笔三(Ajax)
    关于博主noble_
  • 原文地址:https://www.cnblogs.com/bjlhx/p/3177400.html
Copyright © 2011-2022 走看看