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方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM