导航

EF 示例

Posted on 2016-03-08 15:29  杨彬Allen  阅读(292)  评论(0编辑  收藏  举报

EF有三种数据库访问方式,这里只介绍Code First。

1、DB First,类似Linq to sql中拖拽一个DB到方案中

2、Model First,没试过,不能自动生成数据库只能生成表

3、Code First,手写实体类,经过配置后,EF会自动创建数据库和表

Code First配置需经过两步

一、手写实体类,实体类的类名对应着数据库的表名

    public class Sys_User
    {
        [Key]
        public int UserId { get; set; }
        public string UserName { get; set; }
    }

需注意几点:类名不可为数据库的关键字,比如SysUser需改成Sys_User;实体类必须要有Key,EF现在支持组合Key。

二、重写上下文

    public class MyContext : DbContext
    {
        public MyContext() : base("name=DefaultConnection") { }
        public DbSet<Sys_User> Sys_User { get; set; }
    }
<configuration>
  <connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=.;Initial Catalog=Biz;user id=sa;password=123456;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;MultipleActiveResultSets=True" />
  </connectionStrings>
</configuration>

测试

using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyContext dbContext = new MyContext();
            //到此尚未创建表,需操作一次数据库才行,只要查看一个表,其他表也会自动生成的
            dbContext.Sys_User.FirstOrDefaultAsync();
        }
    }

    public class Sys_User
    {
        [Key]
        public int UserId { get; set; }
        public string UserName { get; set; }
    }
    public class MyContext : DbContext
    {
        public MyContext() : base("name=DefaultConnection") { }
        public DbSet<Sys_User> Sys_User { get; set; }
    }
}

至此,测试结束,数据库自动创建了Biz数据库和Sys_User表。

数据库初始化的三种行为

EF还自动创建了__MigrationHistory表,此表是首次加载以及每次数据库迁移的时候会触发的

自动创建数据库通常不能满足需求,我们希望Sys_User表创建的同时自动生成一笔管理员账号。

1、CreateDatabaseIfNotExists,默认行为,没有就创建一个。

2、DropCreateDatabaseIfModelChanges,如果模型改变后,自动重新创建一个新的数据库,在开发中非常有用,但也要小心,如果开发进行到一半要改表会丢失数据。

3、DropCreateDatabaseAlways,每次运行都重新生成数据库。

 

using System.ComponentModel.DataAnnotations;
using System.Data.Common;
using System.Data.Entity;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyContext dbContext = new MyContext();
            //到此尚未创建表,需操作一次数据库才行
            dbContext.Sys_User.FirstOrDefaultAsync();
        }
    }

    public class Sys_User
    {
        [Key]
        public int UserId { get; set; }
        public string UserName { get; set; }
    }
    public class MyContext : DbContext
    {
        public MyContext()
            : base("name=DefaultConnection")
        {
            Database.SetInitializer<MyContext>(new MyInitDB());
        }
        public DbSet<Sys_User> Sys_User { get; set; }
    }

    public class MyInitDB:CreateDatabaseIfNotExists<MyContext> //: DropCreateDatabaseIfModelChanges<MyContext>
    {
        /// <summary>
        /// 用一些数据对数据库进行初始化
        /// 当通过Entity Framework的Code First特性第一次创建数据库架构时,会用到这个类。
        /// </summary>
        /// <param name="context"></param>
        protected override void Seed(MyContext context)
        {
            InitialSetup(context);
            base.Seed(context);
        }

        public void InitialSetup(MyContext context)
        {
            context.Sys_User.Add(new Sys_User { UserName = "admin" });
            context.SaveChanges();
        }
    }
}

迁移

 如果开发到一半有表要调整,当我们调整实体类的时候(且选择的是CreateDatabaseIfNotExists模式)时怎么办。

我们在Sys_User实体类中加如Password属性

    public class Sys_User
    {
        [Key]
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
    }

然后运行,报错:Additional information: The model backing the 'MyContext' context has changed since the database was created. Consider using Code First Migrations to update the database 。

然后我们手动去修改数据库表结构,发现依然不行,报一样的错误。就是表__MigrationHistory在作怪。

正确的做法是:

在Nuget Manager下运行Enable-Migrations

Each package is licensed to you by its owner. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages. Some packages may include dependencies which are governed by additional licenses. Follow the package source (feed) URL to determine any dependencies.

Package Manager Console Host Version 2.7.40911.287

Type 'get-help NuGet' to see all available NuGet commands.

PM> Enable-Migrations
View Code

之后在Solution中会生成Migrations文件夹,里面的文件看一下即可,不用太关心。

继续在Nuget Manager下运行Add-Migrations,并输入Name:AddTest后,会看到在Migrations文件夹下产生一笔新的文件:201603220556041_AddTest.cs

namespace ConsoleApplication1.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class AddTest : DbMigration
    {
        public override void Up()
        {
            AddColumn("dbo.Sys_User", "Password", c => c.String());
        }
        
        public override void Down()
        {
            DropColumn("dbo.Sys_User", "Password");
        }
    }
}

继续在Nuget Manager下运行update-database,运行后可发现数据库Sys_User表中已生成Password字段,至此迁移结束。

注意看数据库中的__MigrationHistory表,此时多了一笔数据,就是刚刚的迁移记录!!

MigrationId
-------------------------------
201603220546077_InitialCreate
201603220556041_AddTest

(2 row(s) affected)