上一节我们说到使用Fluent API对实体的配置,但是有一个问题了,在业务中我们可以用到的实体很多,那是不是每个都需要这样去配置,这样就造成我们重写的OnModelCreating方法很庞大了。所以我们需要更好的组织Fluent API的配置。

我们知道modelBuilder的Entity<T>泛型方法的返回值是EntityTypeConfiguration<T>泛型类。

所以我们可以定义一个继承自EntityTypeConfiguration<T>泛型类的类来定义domain中每个类的数据库配置,我们在这个自定义类的构造函数中使用我们上次提到的那些方法配置数据库的映射。

public class CustomerEntityConfiguration:EntityTypeConfiguration<Customer>

{
        public CustomerEntityConfiguration()
        {
            HasKey(c => c.IDCardNumber).Property(c => c.IDCardNumber).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
            this.Property(c => c.IDCardNumber).HasMaxLength(20);
            this.Property(c => c.CustomerName).IsRequired().HasMaxLength(50);
            this.Property(c => c.Gender).IsRequired().HasMaxLength(1);
            this.Property(c => c.PhoneNumber).HasMaxLength(20);
        }

}

就这么简单。

但是新的问题,我们通过Fluent API改变数据库映射时,Code First会如何处理与新的数据库映射不匹配的数据库呢?

其实Code First 中的Database类的SetInitializer方法会设定Code First如何根据Fluent API数据库映射配置初始化数据库。

SetInitializer方法的参数可以使用以下三个泛型类的对象:

1.0CreateDatabaseIfNotExists<T>:只有在没有数据库的时候会创建新的数据库

2.0DropCreateDatabaseIfModelChanges<T>:只要Fluent API配置的数据库映射发生变化的时候,就把以前的数据库删掉,根据新的配置重新建立数据库。这种方式比较适合开发数据库,可以减少开发人员的工作量。

3.0DropCreateDatabaseAlways<T>:不管数据库映射或者model是否发生变化,每次都重新删除并根据配置重建数据库。

一般Database.SetInitializer都是在应用程序的入口,比如Global.ascx.cs,Main方法等地方调用的。

假设我们在测试环境中测试对Product类的相关操作,我们需要一些ProductCatalog的基础数据,因为Product中有一个Productcatalog的引用。我们可以定义一个自己的数据库初始化类,继承DropCreateDatabaseAlways,让Code First每次在执行测试之前都删除掉原来的数据库并且插入一些ProductCatalog的测试数据。

public class DropCreateOrderDatabaseWithSeedValueAlways : DropCreateDatabaseAlways<OrderSystemContext>
   {
       protected override void Seed(OrderSystemContext context)
       {
           context.ProductCatalogs.Add(new ProductCatalog { CatalogName = "DELL E6400", Manufactory = "DELL", ListPrice = 5600, NetPrice = 4300 });
           context.ProductCatalogs.Add(new ProductCatalog { CatalogName = "DELL E6410", Manufactory = "DELL", ListPrice = 6500, NetPrice = 5100 });
           context.ProductCatalogs.Add(new ProductCatalog { CatalogName = "DELL E6420", Manufactory = "DELL", ListPrice = 7000, NetPrice = 5400 });
       }
   }

我们在测试类的测试初始化方法中就可以指定Code First使用我们自定义的初始化类进行数据库的初始化:

Database.SetInitializer(new DropCreateOrderDatabaseWithSeedValueAlways());

这样就可以使用我们初始化的时候的数据进行测试了:

[TestMethod]
        public void CanAddProduct()
        {
            OrderSystemContext unitOfWork = new OrderSystemContext();
            ProductRepository repository = new ProductRepository(unitOfWork);
            ProductCatalog catalog = repository.SearchProductCatalog(c => c.CatalogName == "DELL E6400", 1, 10)[0];
            Product product = new Product { Catalog = catalog, CreateDate = DateTime.Parse("2010-2-10"), ExpireDate = DateTime.Parse("2012-2-10") };
            repository.AddNewProduct(product);
            unitOfWork.CommitChanges();
        }

总结:这章讲了业务中我们多个实体该如何配置Fluent API,和Fluent API 配置的改变时Code First同步到数据库的几种方式的区别。

Code First03---CodeFirst根据配置同步到数据库的三种方式的更多相关文章

  1. laravel记录笔记Laravel 连接数据库、操作数据库的三种方式

    laravel中提供DB facade(原始查找).查询构造器.Eloquent ORM三种操作数据库方式 1.连接数据库 .env 数据库配置 DB_HOST=localhost dbhost DB ...

  2. JDBC操作数据库的三种方式比较

    JDBC(java Database Connectivity)java数据库连接,是一种用于执行上sql语句的javaAPI,可以为多种关系型数据库提供统一访问接口.我们项目中经常用到的MySQL. ...

  3. PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)

    PHP与MySQL的连接有三种API接口,分别是:PHP的MySQL扩展 .PHP的mysqli扩展 .PHP数据对象(PDO) ,下面针对以上三种连接方式做下总结,以备在不同场景下选出最优方案. P ...

  4. php连接MySQL数据库的三种方式(mysql/mysqli/pdo)

    引言 PHP与MySQL的连接有三种API接口,分别是:PHP的MySQL扩展 .PHP的mysqli扩展 .PHP数据对象(PDO) ,下面针对以上三种连接方式做下总结,以备在不同场景下选出最优方案 ...

  5. 使用DataSet Datatable 更新数据库的三种方式

    1:自动生成命令的条件 CommandBuilder 方法a)动态指定 SelectCommand 属性b)利用 CommandBuilder 对象自动生成 DataAdapter 的 DeleteC ...

  6. log4net 控制台和文件和数据库输出三种方式

    1.新建console应用项目SendEvaluateDataToProvinceConsole 2.选择SendEvaluateDataToProvinceConsole项目右键 选择 管理NuGe ...

  7. jdbc链接数据库的三种方式

    /** * jdbc连接数据库 * @author APPle * */ public class Demo1 { //连接数据库的URL private String url = "jdb ...

  8. spring mvc 通过配置xml访问控制器的三种方式

    (一)通过 name 来一一映射(默认) (二)通过简单url 来指定映射,key 表示访问url value 是bean的ID (三)通过控制类的类名控制器,访问时类名首字母需要小写 <!-- ...

  9. kafka的生产者配置以及发送信息的三种方式

    1.Fire-and-forget 这种方式是不管发送成功与否,客户端都会返回成功.尽管大多数的时候Kafka 在发送失败后,会自己重新自动再一次发送消息,但是也会存在丢失消息的风险 Producer ...

随机推荐

  1. JS-用js的for循环实现九九乘法表以及其他算数题等

    <!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>f ...

  2. 无法加载协定为xx的终结点配置部分,因为找到了该协定的多个终结点配置。请按名称指示首选的终结点配置部分。

    当在vs 2008中添加服务引用后,如果"更新"服务引用,或"删除"该服务引用后再次加入后,在运行时会出现此错误.这是因为在"更新/删除"服 ...

  3. case when then else end

    1.根据数据库表中特定的值进行排序显示 select * from tablename where order by case when columname='' then 1 wnen column ...

  4. 给ubuntu的docky添加可以直接打开的图标

    在/usr/share/applications和/usr/share/app-install/desktop寻找需要的图标,没有就自己做一个 eclipse的图标 [Desktop Entry] V ...

  5. Linux下的网络环境配置

  6. iOS7以上图片模糊效果

    模糊后的效果 模糊后的效果 框架UIImage+BlurredFrame里的 applyLightEffectAtFrame方法 例如 bgImage = [bgImage applyLightEff ...

  7. phpmyadmin 链接远程mysql

    这个只是自己的笔记 新手 不记下来以后又忘记了~ 在这以前已经给mysql设置了可以远程连接的账户 版本 phpMyAdmin-4.2.11-all-languages 解压到D盘下www   本地环 ...

  8. Lua 之数据结构

    Lua 之数据结构 数组 通过整数下标访问的table中的元素,即是数组,下标默认从1开始. 一个创建二维数组的例子: mt = {} , do mt[i] = {} , do mt[i][j] = ...

  9. JavaScript 五种(构造方式)继承

    一.对象冒充 function Parent(username){ this.username = username; this.hello = function(){ alert(this.user ...

  10. 【转】随机函数 rand() srand() 以及seed的原理

    from:http://blog.csdn.net/feige2008/article/details/6943885   标准库<cstdlib>(被包含于<iostream> ...