原文: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; }
}
}
备注:
- byte生成的字段类型对应tinyint
- 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有三种初始化方式(参见下面三个类):
- DropCreateDatabaseIfModelChanges 模型一变重建数据库(开发阶段)
- CreateDatabaseIfNotExists 数据库不存在时创建数据库(适合项目正式上线)
- 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方法
