上一节我们说到使用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. 打包jar文件 外部调用资源 so等

    一个非常好的从jar文件中加载so动态库方法,在android的gif支持开源中用到.这个项目的gif解码是用jni c实现的,避免了OOM等问题. 项目地址:https://github.com/k ...

  2. VGA 视频输出

    VGA Video Output by Nathan Ickes Introduction VGA is a high-resolution video standard used mostly fo ...

  3. dos命令复制当天生成的以日期为文件名的文件

    1.利用SqlServer的自动备份功能,将数据自动备份,备份出的文件格式如下:             db_backup_201001270930.bak 2.编辑bat脚本            ...

  4. Spring MVC学习笔记——Controller接口

  5. Log4j、slf4j

    1.Log4j 1.1 Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出位置)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志 ...

  6. C#----XML操作小结

    结点和元素的区别: * 结点和元素的区别:  * 结点包括元素,结点可以是一个文本,也可以是一个属性,结点包括的类型在XmlNodeType中总结.  * <root id="这是一个 ...

  7. C++ 生成 dll 和调用 dll 的方法实例(转)

    1)生成dll 建立两个文件 xxx.h , xxx.cpp xxx.h内容如下: #ifdef BUILD_XXX_DLL#define EXPORT __declspec(dllexport)#e ...

  8. Java并发编程核心方法与框架-ExecutorService的使用

    在ThreadPoolExecutor中使用ExecutorService中的方法 方法invokeAny()和invokeAll()具有阻塞特性 方法invokeAny()取得第一个完成任务的结果值 ...

  9. java 使用BeanUtils.copyProperties(Object source,Object target) 复制字段值

    BeanUtils.copyProperties(person, wsPerson);把person的字段值,复制给wsPerson // 只复制两个实体中,字段名称一样的 很有用的一个功能...

  10. 图书管理系统——APP平台开发

    http://www.w3school.com.cn/php/ 初步计划采用PHP 开发网站. 一定要独立建立一套图书管理系统, 尤其唯一性质的概念,整合,甚至中英文图书概念的而整合.一本书一个页. ...