我最近几天正在学习Entity Framework Code First.我打算分享一系列的学习笔记,今天是第一部分:

为什么要使用Code First:

近 年来,随着domain driven design的推广,以前那种先建好数据库,然后再编写代码的方式受到了越来越多的质疑。因为使用这种开发方式很难适应领域内业务逻辑的改变,它需要当每 次领域发生改变的时候,先改变数据库,然后再改变业务逻辑和实体的代码,开发周期比较长,而且不利于单元测试。所以随着domain driven design一同推广的还有Persistence Ignorance 原则和POCO(Plain Old CLR Object). Persistence Ignorance principle说白了就是把domain driven design中的实体,值对象,服务与数据存储功能完全隔离,使他们不掺杂任何与数据存储相关的代码。在随后的实例中,大家可以看到如何通过Code First实现这些。

所谓的Code First就是先写业务逻辑部分的代码,实现domain driven design当中的实体,值类型和服务,然后通过Code First默认的习惯或者配置把他们映射到数据库中去。这样做一方面可以让我们先把全部的精力投放到业务逻辑的设计和实现中,并且可以在实现业务逻辑后, 使用一些Mock工具单独对业务逻辑代码进行测试。另一方面,当我们对业务逻辑进行proof-of-concept时,可以通过几个简单的界面就可以做 出prototype去给客户演示了。通过使用Code First方式,使我们能更快的对应业务逻辑的改变和原型搭建。所以Code First非常适用于使用domain driven design的新建项目使用。

关于使用Code First的好处以及使用它的场合,相信通过前面的介绍大家已经清楚了,还是让我们回到代码,通过最简单的一个实例程序看看Code First是怎么按照他的约定来实现数据库的映射的。

Code First遵循的是Convention over Configuration的原则,也就是说如果你对领域中的各类对象的映射没有进行配置的话, Code First就会按照他的默认习惯进行领域对象与数据库的映射。

我在本系类的日记中使用的实例是给公司内部新员工培训使用的一个简单的订单管理系统,包含客户,订单,订单条目,产品,产品目录等实体和值对象。

让我们先考虑最简单的产品目录吧,假设我们的产品目录是一个值对象包含以下属性:

public class ProductCatalog
    {
        public int ProductCatalogId { get; set; }
        public string CatalogName { get; set; }
        public string Manufactory { get; set; }
        public decimal ListPrice { get; set; }
        public decimal NetPrice { get; set; }
    }

怎么才能够让Entity Framework认识你定义的值对象并且把它映射成数据库中的表呢?你需要定义一个继承DbContext类的子类,然后在这个子类中添加一个泛型DbSet的属性,类型参数就是你自定义的ProductCatalog类。

public class OrderSystemContext:DbContext
    {
        public DbSet<ProductCatalog> ProductCatalogs { get; set; }
    }

然后你可以使用你定义的OrderSystemContext类进行数据操作了。

var context = new OrderSystemContext();

var catalogs = context.Catalogs.Where(c => c.ProductCatalogId == 1);

现在就让我们来介绍一下Entity Framework Code First中的映射习惯吧。

1. 数据库映射:Code First 默认会在本地的SQL Expression数据库中建立一个和DbContext的子类的全名相同的数据库,全名指的是命名空间加上类名。当然后边会介绍怎么进行配置。

2.表映射:Code First 默认会按照类型名复数建立数据表,比如说ProductCatalog类对应的表名就叫ProductCatalogs.后边会介绍如何改变默认的表名。

3.
列映射:Code First
默认会按照类中的属性名建立column,它还有默认的数据类型映射习惯,int会映射为interger,string会映射为
nvarchar(max),decimal会映射为decimal(18,2)。后边会介绍如何更改column的名称,类型以及其他特性。

4.主键映射:Code First 默认会在类的属性中需找名字为Id或类型名称+Id的int类型的属性作为主键,并且是自增字段。这些也是可以改的。

这个程序执行完之后就会在默认的SQL Expression中建立一个名为xxx.OrderSystemContext的类,并且建立一个名字为ProductCatalogs的表,表的具体结构如下:


然,我们既然使用domain driven
design就完全应该按照我们领域中的实际业务情况设计我们的类,这样就不可能使我们的类完全遵守Code
First的习惯,接下来的学习日记将主要具体介绍如何通过Code First的配置功能将我们领域中各种各样的类和类之间的关系映射到数据库中。

http://www.cnblogs.com/lk8167/archive/2013/01/07/2849443.html

Entity Framework Code First 学习日记(1)精的更多相关文章

  1. Entity Framework Code First学习系列目录

    Entity Framework Code First学习系列说明:开发环境为Visual Studio 2010 + Entity Framework 5.0+MS SQL Server 2012, ...

  2. Entity Framework Code First学习系列

    Entity Framework Code First学习系列目录 Entity Framework Code First学习系列说明:开发环境为Visual Studio 2010 + Entity ...

  3. Entity Framework Code First 学习

    1.添加entityframework 项目-管理解决方案的 NuGet 程序包-联机-Entity Framework 2.code first Migration 工具->库程序包管理器-& ...

  4. Entity Framework Code First (一)Conventions

    Entity Framework 简言之就是一个ORM(Object-Relational Mapper)框架. Code First 使得你能够通过C#的类来描述一个模型,模型如何被发现/检测就是通 ...

  5. Entity Framework Code First约定

    Code First使你能够通过C# 或者 Visual Basic .NET来描述模型,模型的基本规则通过使用约定来进行检查,而约定就是一系列内置的规则. 在Code First中基于类的定义通过一 ...

  6. Entity Framework Code First实现乐观并发

    Entity Framework Code First实现乐观并发 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: h ...

  7. Entity Framework Code First数据库连接

    1. 安装Entity Framework 使用NuGet安装Entity Framework程序包:工具->库程序包管理器->程序包管理器控制台,执行以下语句: PM> Insta ...

  8. Entity Framework Code First属性映射约定

    Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...

  9. Entity Framework Code First关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

随机推荐

  1. 谈谈IE针对Ajax请求结果的缓存

    在默认情况下,IE会针对请求地址缓存Ajax请求的结果.换句话说,在缓存过期之前,针对相同地址发起的多个Ajax请求,只有第一次会真正发送到服务端.在某些情况下,这种默认的缓存机制并不是我们希望的(比 ...

  2. 缺省源和 Vim 配置

    缺省源 #include <bits/stdc++.h> #define x first #define y second #define pb push_back #define mp ...

  3. Hdoj 2018.母牛的故事 题解

    Problem Description 有一头母牛,它每年年初生一头小母牛.每头小母牛从第四个年头开始,每年年初也生一头小母牛.请编程实现在第n年的时候,共有多少头母牛? Input 输入数据由多个测 ...

  4. 【BZOJ4061】[Cerc2012]Farm and factory(最短路,构造)

    [BZOJ4061][Cerc2012]Farm and factory(最短路,构造) 题面 BZOJ 然而权限题QwQ. 题解 先求出所有点到达\(1,2\)的最短路,不妨记为\(d_{u,1}, ...

  5. portainer图形化监控

    步骤1,在Swarm集群中创建一个新的覆盖网络:$ docker network create --driver overlay --attachable portainer_agent_networ ...

  6. string的基本用法

    #include <iostream> #include<string> #include<vector> #include<algorithm> us ...

  7. js获取元素位置和style的兼容性写法

    今天说一下js获取元素位置和style的方法.当然不只是element.style那么简单.. 主角:getBoundingClientRect,getClientRects,getComputedS ...

  8. C# Winform 对话框控件&简单记事本

    一.对话框 1.弹出可供用户选择“确定”.“取消”的对话框 Dialogresult dr =  MessigeBox.Show("这里显示的是对话框的内容","这里显示 ...

  9. python描述器

    描述器定义 python中,一个类实现了__get__,__set__,__delete__,三个方法中的任何一个方法就是描述器,仅实现__get__方法就是非数据描述器,同时实现__get__,__ ...

  10. 面试集——redis

    背景:该贴主要用来记面试过程中redis相关的问题,方便后期回顾. 为什么说Redis是单线程的以及Redis为什么这么快! https://blog.csdn.net/xlgen157387/art ...