关于EF CodeFirst的文章院子里有很多的学习资料,但大多数都是一些讲Model通过特性或是Fluent API与数据库之间形成映射的关系,看了相关的文章之后,Model如何映射到数据还是有些迷糊,最近看了qouoww的这个系列文章http://www.cnblogs.com/qouoww/archive/2011/12/31/2309066.html,感觉不错,写下一个简单的demo作为总结,一起学习共勉。

既然是采用CodeFirst的方式来编程的话,那么首先很明显一点我们得自己定义一个数据库上下文对象,如下所示:

 public class BaseDbContext<TContext> : DbContext
where TContext : BaseDbContext<TContext>, new()
{
public BaseDbContext()
: base("DefaultConnection")
{ }
}

  构造函数中引用的基类构造函数,如下所示:

        //     Constructs a new context instance using the given string as the name or connection
// string for the database to which a connection will be made. See the class
// remarks for how this is used to create a connection.
//
// 参数:
// nameOrConnectionString:
// Either the database name or a connection string.
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
public DbContext(string nameOrConnectionString);

   因此EF中默认的数据库连接字符串就是配置文件中默认的连接字符串:

接下来我们我们创建一个数据库迁移配置类,这个类主要是用来封装由Model变化而引起的数据库结构的变化。如下所示:

 public sealed class TestConfiguration : DbMigrationsConfiguration<TestDbContext>
{
public TestConfiguration()
{
this.AutomaticMigrationsEnabled = true;
this.AutomaticMigrationDataLossAllowed = true;
}
}

 这样我们就启动了迁移功能。紧接着我么来创建数据库迁移类来封装数据库迁移的相关方法,如下所示:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(TestDatabaseMigrator), "MigrateDatabase")]
namespace CodeFirst.Context
{
public class TestDatabaseMigrator
{
public static void MigrateDatabase()
{
DbMigrator dbMigrator = new DbMigrator(new TestConfiguration());
dbMigrator.Update();
using (TestDbContext dbContext = new TestDbContext())
{
dbContext.Database.Initialize(true);
}
}
}
}

  我们可以看到DbMigrator类是以数据库迁移类作为参数实例化的, dbMigrator.Update()这句代码可以保证我们的目标数据库都是与Model映射成的最新的数据库结构。注意这一句话:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(TestDatabaseMigrator), "MigrateDatabase")]

   WebActivator 允许您定义一个 PreApplicationStartMethod 属性,用于标记作为东西您获取 Web 应用程序启动时调用的方法,这样就可以保证先初始化我们的数据库。WebActivatorEx还有一个PostApplicationStartMethod方法,改方法是在全局的asax Application_Start 后调用的方法。

TestDbContext的定义如下:

 public class TestDbContext : BaseDbContext<TestDbContext>
{
public DbSet<Test> MyTest { get; set; }
}

  TestModel定义如下,用于与数据库映射成对应的表,请记住Model必须要有主键,否则会报错!

  public class Test
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

  我们启动web应用程序后,在vs中附带的数据库中可以看到EF创建的数据库:数据库名是与配置文件中的数据库名一致,而表名则是根据默认的约定生成的,即Model+s就是默认生成的表名。

但是上面看起来很别扭,首先,数据库要生成到SqlServer中,那么我们修改下配置文件:

    <add name="DefaultConnection" connectionString="Data Source=.;Initial Catalog= EF.CodeFirst;Integrated Security=True" providerName="System.Data.SqlClient" />

然后我们想自己定义它生成的表名及相关的索引,注释之类的,那么我们首先要创建一个数据库初始化器:

 /// <summary>
/// 数据库初始化器
/// </summary>
/// <typeparam name="T"></typeparam>
public class InitializerComposite<T>: IDatabaseInitializer<T>
where T : DbContext
{
private readonly List<IDatabaseInitializer<T>> initializers; public InitializerComposite(params IDatabaseInitializer<T>[] databaseInitializers)
{
this.initializers = new List<IDatabaseInitializer<T>>();
this.initializers.AddRange(databaseInitializers);
} /// <summary>
/// 执行数据库初始化器
/// </summary>
/// <param name="context"></param>
public void InitializeDatabase(T context)
{
foreach (var initializer in this.initializers)
{
initializer.InitializeDatabase(context);
}
}
}

同时我们需要修改下数据库上下文对象的基类,加入如下代码:

 /// <summary>
/// 获取表的名字
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public virtual string GetTableName(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
} string modelName = type.Name;
return modelName;
} /// <summary>
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (modelBuilder == null)
{
throw new ArgumentNullException("modelBuilder");
}
// 定义表名规则
modelBuilder.Entities().Configure(entity => entity.ToTable(this.GetTableName(entity.ClrType)));
Database.SetInitializer(new InitializerComposite<TContext>());
}

表名直接就是利用Model的类名来生成,启动web程序,我们打开SqlServer,我们可以看到:数据库名在配置文件中指定,表名就是Model的类名Test,而不是默认的Tests。我们看下生成的表的结构:

当然生成的字段的数据长度都是系统默认生成的长度,这个我们也可以修改,将在后面的文章中进行说明。

但是有时候我们想在生成数据库的时候,同时有一些初始化的数据呢?这个时候我们就要在数据库迁移配置类中的Seed中加入一些初始数据:

 /// <summary>
/// 对数据库中的进行相关的初始化操作
/// </summary>
/// <param name="context"></param>
protected override void Seed(TestDbContext context)
{
var test1 = new Test() { Name="aa", Age=12 };
var test2= new Test() { Name = "bb", Age = 12 };
var test3 = new Test() { Name = "cc", Age = 12 };
var tests = new List<Test> { test1, test2, test3};
tests.ForEach(c => context.MyTest.AddOrUpdate(x => x.Name, c));
context.SaveChanges();
base.Seed(context);
}

我们再次打开数据库,可以发现,生成的表里面已经有了我们初始化的数据了:

好了,EF CodeFirst的一些简单运用写到这里,日后将陆续更新。

EF CodeFirst-----简单demo示例的更多相关文章

  1. Ext简单demo示例

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  2. EF CodeFirst 实例Demo

    一直想搞一个EFCodeFirst的Demo,让自己通过实例真正了解CodeFirst,方便以后有需求的时候可以有思路.网上查了很多资料,发现很多博主的文章大量重复,根据推荐步骤走并不一定能够成功,而 ...

  3. EF CodeFirst简单实例

    运行环境:VS2012,添加的EntityFramework为6.0.2 版本不用太关心,只要知道原理就行了: 基本代码就这几行: namespace ConsoleApplication1 {    ...

  4. EF CodeFirst生成数据库到Sqlserver中

    EF CodeFirst简单实例这篇文章介绍了如何用EF去快速生成数据库.但是这个并没有生成到sqlserver中,总觉得不爽.下面就来讲一下,如何将数据库生成到sqlserver中. 按照EF Co ...

  5. Django实战(一)之简单Demo

    菜鸟教程上Django安装可供参考: 参考链接: http://www.runoob.com/django/django-install.html 菜鸟教程上如果不行的话,下面博客网址可以供参考 Li ...

  6. 写一个EF的CodeFirst的Demo

    写一个EF的CodeFirst的Demo 今天打算写一个关于EF的CodeFirs的一个小Demo.先略说一个EF的三种与数据库,怎么说,叫映射么,好吧,那就这么叫吧,就是一个是ModelFirst就 ...

  7. 3.翻译系列:EF Code-First 示例(EF 6 Code-First系列)

    原文链接:http://www.entityframeworktutorial.net/code-first/simple-code-first-example.aspx EF 6 Code-Firs ...

  8. EF CodeFirst系列(1)---CodeFirst简单入门

    1.什么是CodeFirst 从EF4.1开始,EF可以支持CodeFirst开发模式,这种开发模式特别适用于领域驱动设计(Domain Driven Design,大名鼎鼎的DDD).在CodeFi ...

  9. 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...

随机推荐

  1. 2014_GCJ_A

    题目链接:http://code.google.com/codejam/contest/2984486/dashboard#s=p0 最想吐槽的是想些DFS过小数据,居然写不出来,不知道我这半年的AC ...

  2. Android 4.4 KitKat, the browser and the Chrome WebView

    Having V8 as the JavaScript engine for the new web view, the JavaScript performance if much better, ...

  3. 纯CSS3实现3D动画导航,html5 webRTC技术实现免费网页电话拨打

    花了一周的时间完成了 说吧 (免费网页电话) 的前端开发工作,先将技术点总结如下: 免费电话采用最新的html5 webRTC 技术 实现互联网和电信MIS网互通实现网页电话,目前只有 google ...

  4. 将Asp.Net页面输出到EXCEL里去

    其实,利用ASP.NET输出指定内容的WORD.EXCEL.TXT.HTM等类型的文档很容易的.主要分为三步来完成. 一.定义文档类型.字符编码   Response.Clear(); Respons ...

  5. LVM quick start

    这里记录一些任务用到的快速命令,详细LVM管理可参考: http://wenku.baidu.com/view/c29b8bc4bb4cf7ec4afed0ad.html 1.把home分区的磁盘空间 ...

  6. hdu 1531(差分约束)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1531 差分约束的题之前也碰到过,刚好最近正在进行图论专题的训练,就拿来做一做. ①:对于差分不等式,a ...

  7. php中include包含文件路径查找过程

    首先,“路径”分为三种: 1.绝对路径,以/开头(unix系统)或c:等盘符开头(windows系统). 2.相对路径,以.开头,有./(当前目录)和../(上级目录). 3.其他路径,不是绝对路径和 ...

  8. NameNode HA滚动升级方案

    Hadoop 滚动升级非常方便,只需要在配置中增加一些选项就可以通过Hadoop自身的代码进行完成. 步骤: 1.首先到需要升级的NameService的Active NameNode上面,比如我们1 ...

  9. 超级内存NVDIMM:下一代数据中心存储关键技术

    1.背景介绍 连接到互联网的设备数量不断增长,到2015年,将达到150亿之多.而数据中心的压力也随之增加,唯有采用新的技术才能进一步提升其效率和性能. 相比于HDD传统硬盘,固态硬盘大大增加了I/O ...

  10. MyBatis笔记——初次环境配置

    简单介绍 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBati ...