• EF自动创建数据库


    原文:https://www.cnblogs.com/FGang/p/11262232.html

    一、创建表映射实体类

    复制代码
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Common;
    using System.Data.Entity;
    using System.Linq;
    using System.Web;
    namespace DBClientEntity
    {
        [Table("User")]//表名
        public class User
        {
            [Key] //主键
            [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]//非自增长,自增长为Identity
            [MaxLength(20)]
            [Column(TypeName= "varchar")] 
            public string ID { get; set; }
            
            [Required]//必填
            [MaxLength(50)]//字段长度 ,若不指定长度则生成 的表默认为nvarchar(max)
            [Column(TypeName = "varchar")] //指定字段类型为varchar,而非默认的nvarchar
            public string Password { get; set; }
            [Required]
            public byte Type { get; set; }
            [Required]
            public System.DateTime CreateTime { get; set; }
        }
    }
    复制代码

    备注:

    1. byte生成的字段类型对应tinyint
    2. byte[]数组生成的字段类型对应varbinary(MAX)

         

    创建好表实体类后,接着就是创建数据库上下文(继承DbContext)并将实体类添加进来。

    代码示例如下:

    复制代码
    using DBClientEntity;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Core.Objects;
    using System.Data.Entity.Infrastructure;
    using System.Data.Entity.ModelConfiguration;
    using System.Linq;
    using System.Reflection;
    using System.Web;
    namespace DBClientEntity
    {
        /// <summary>
        /// EF数据库上下文
        /// </summary>
        public class DbClientContext : DbContext
        {
           //connStr为数据库连接串或app.config中的数据库连接名称
            public DbClientContext(string connStr)
            : base(connStr)
            {
    
            }
            /// <summary>
            /// 实体类表
            /// </summary>
            public DbSet<User> User { get; set; }
        }
    }
    复制代码

    EF自动创建数据库需要我们告诉数据库如何进行初始化;如创建表后是否需要插入一些基础数据,是否 需要创建存储过程、触发器等。还有就是EF有三种初始化方式(参见下面三个类):

    1. DropCreateDatabaseIfModelChanges 模型一变重建数据库(开发阶段)     
    2. CreateDatabaseIfNotExists  数据库不存在时创建数据库(适合项目正式上线)
    3. DropCreateDatabaseAlways  每次启动程序时都重新创建数据库(提前是数据库不能被任何程序占用,包含sqlserver管理工具打开运行也会报错被使用,此方式不太可取,建议不要使用)

      下面示例如何创建初始化器并插入一些数据、创建触发器(首次创建数据库才会执行Seed方法)

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    namespace DBClientEntity
    {
        /// <summary>
        /// 数据库初始化器
        /// </summary>
        public class DBIfNotExistsInitializer : CreateDatabaseIfNotExists<DbClientContext>
        
            public override void InitializeDatabase(DbClientContext context)
            {
    
               
                base.InitializeDatabase(context);
            }
            /// <summary>
            /// 初始化一些数据,模型有变化或首次运行才会执行
            /// </summary>
            /// <param name="context"></param>
            protected override void Seed(DbClientContext context)
            {
    
                #region 创建触发器(不处理异常)
                //[UserInfo]表触发器
                string fileName = "trUserInfo.Trigger.sql";
                string sql = GetSqlFile(fileName);
                if (!string.IsNullOrEmpty(sql))
                {
                    try
                    {
                        context.Database.ExecuteSqlCommand(sql);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(string.Format("执行脚本{0}出错! {1}", fileName, ex.Message));
                    }
                }
    
                #endregion
                //创建内置帐号
                User item = new User();
                item.ID = "admin";
                item.Password = "111111";
                item.Type = 2;
                item.CreateTime = DateTime.Now;
                if (context.User.Count(x => x.ID == item.ID) < 1)
                {
                    context.User.Add(item);
                    context.SaveChanges();
                }
                base.Seed(context);
            }
            /// <summary>
            /// 读取资源文件中的脚本文件
            /// </summary>
            /// <param name="fileName">如UserInfo.Trigger.sql</param>
            /// <returns></returns>
            private string GetSqlFile(string fileName)
            {
                string sql = "";
                string nameSpace = this.GetType().Namespace;
                Assembly assembly = Assembly.GetExecutingAssembly();
                Stream stream = assembly.GetManifestResourceStream(nameSpace + "." + fileName);
                if (stream != null)
                {
                    try
                    {
                        //默认编码加载脚本文件
                        using (StreamReader reader = new StreamReader(stream, Encoding.Default))
                        {
                            sql = reader.ReadToEnd();
                        }
                    }
                    catch
                    {
                    }
                    finally
                    {
                        stream.Close();
                    }
                    // 返回读取结果
                }
                return sql;
            }
        }
    }
    复制代码

     在创建完DBIfNotExistsInitializer数据库初始化器类后,需要在程序每一次访问数据库前,告诉EF使用该初始化器进行初始化。

    代码如下 :

    Database.SetInitializer<DbClientContext>(new DBIfNotExistsInitializer());     

    说明:

    DbClientContext 是之前创建的数据库上下文,访问数据库时必须使用该类,否则会造成EF在数据库首次创建时不会执行Seed方法

  • 相关阅读:
    【Java】LinkedHashMap
    【Java】 HashMap
    【译】Solr in Action 第三章
    【译】Solr in Action 第二章
    【译 】Solr in Action 第一章
    【Three.js】OrbitControl 旋转
    【翻译】JNA调用DLL
    .Net使用Redis详解之ServiceStack.Redis
    C#操作redis
    ECharts图介绍
  • 原文地址:https://www.cnblogs.com/zhang1f/p/12579376.html
Copyright © 2020-2023  润新知