惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
腾讯CDC
The GitHub Blog
The GitHub Blog
大猫的无限游戏
大猫的无限游戏
Microsoft Security Blog
Microsoft Security Blog
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
Vercel News
Vercel News
P
Proofpoint News Feed
雷峰网
雷峰网
博客园_首页
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
V
V2EX
F
Fortinet All Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
MyScale Blog
MyScale Blog
S
SegmentFault 最新的问题

博客园 - Henry Cui

招聘高级.Net工程师 Node.js Web开发(二)认识Express(上) Node.js Web开发(一)从零开始 Html5 Step by Step(二) 本地存储 HTML 5 Step by Step(一) 拖放API Git学习笔记(一)初识Git DDD中的Specification模式 Silverlight 4之旅(三)数据绑定(中) Silverlight 4之旅(二)数据绑定(上) Silverlight 4之旅(一) .Net 4.0 Parallel 编程之旅 .Net 4.0 Parallel 编程(九)Task中的数据共享(下) .Net 4.0 Parallel编程(八)Task中的数据共享(中) .Net 4.0 Parallel 编程(七)Task中的数据共享(上) .Net 4.0 Parallel 编程(六)Task(下) .Net 4.0 Parallel 编程(五)Task(中) .Net 4.0 Parallel 编程(四) Task(上) Entity Framework Code-First(上) Entity Framework POCO T4模板使用
Entity Framework Code-First(下)
Henry Cui · 2010-08-08 · via 博客园 - Henry Cui

2010-08-08 15:38  Henry Cui  阅读(8368)  评论()    收藏  举报

上篇文章中看过在CTP4中Code-First的功能,这篇文章会就Code-First的自定义数据库映射、相关的Api进行一些说明。

回顾

上篇文章中我们看到了Code-Firts带来的强大的功能。其中我们来看看前面定义的一个实体:

    public class Department
    {
        public int DepartmentID { get; set; }
        public string DepartName { get; set; }

        public virtual ICollection<Employee> Employees { get; set; }
    }

而之后我们需要添加一个属性,一个Remark的属性:

    public class Department
    {
        public int DepartmentID { get; set; }
        public string DepartName { get; set; }
        public string Remark { get; set; }

        public virtual ICollection<Employee> Employees { get; set; }
    }

我们再来运行下我们的测试会出现下面的错误:

image

错误告诉我们,数据库建立了之后context已经改变了,要么手动地维护数据库,或则删除数据库,或则使用Database.SetInitializer方法来自动的删除或则重建数据库。

Database.SetInitializer

在Entity Framwwork CTP4 Code-Fist程序库中提供了一个非常有用的development-time特性让我们来自动地更新我们的数据库。当我们的Model Class发生改变时,EF可以自动识别出来,然后就可以重建我们的数据库去跟Class的结构保持同步。

当然,要注意的一点是重建数据库,所以在开发的时候是非常方便的,如果你不想自己的数据库中的数据丢失的话,还是去手动的修改数据库的结构。下面我们来看下如何使用:

        [TestInitialize()]
         public void CodeFisrtTestInitialize() 
        {
            Database.SetInitializer<NorthwindContext>(new RecreateDatabaseIfModelChanges<NorthwindContext>());
        }

我们在测试初始化的时候调用Database.SetInitializer方法。

image

OnModelCreating、ModelBuilder

在之前的例子中我们看到的都是Model跟数据库中的表名、字段名都是一一对应的,如果我们需要结构有所不同呢?EF Code-First中提供自定义数据库结构的功能给我们了。我们可以通过重写DbSet中的OnModelCreating方法,去添加我们的Mapping信息。

1)数据库表明的映射

首先我们先来看看数据表明的映射。这里我需要将Departments映射到表名为tb_Departments的表上:

        protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Department>().MapSingleType().ToTable("tb_Departments");
        }

运行下测试,我们看看数据库中:

image

2)字段的映射

我想在数据库中的每个字段中都会加上前缀“col_”,比如DepartmentID就是“col_DepartmentID”:

        protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Department>().MapSingleType(depart => new { 
                col_DepartmentID = depart.DepartmentID,
                col_DepartmentName = depart.DepartName,
                col_Remark = depart.Remark
            })
            .ToTable("tb_Departments");
        }

我们可以看到运行之后:

image

3)复杂类型的映射

在这里我们添加一个CreateInfo的Model:

    public class CreateInfo
    {
        public string CreateUserID { get; set; }

        public DateTime? CreateDate { get; set; }
    }

我们Department信息中包含了一个CreateInfo类型的属性:

    public class Department
    {
        public int DepartmentID { get; set; }
        public string DepartName { get; set; }
        public string Remark { get; set; }

        public CreateInfo CreateInfo { get; set; }

        public virtual ICollection<Employee> Employees { get; set; }
    }

我们重写编写我们的Mapping信息:

        protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Department>().MapSingleType(depart => new { 
                col_DepartmentID = depart.DepartmentID,
                col_DepartmentName = depart.DepartName,
                col_Remark = depart.Remark,
                col_CreateUserID= depart.CreateInfo.CreateUserID,
                col_CreateDate = depart.CreateInfo.CreateDate
            })
            .ToTable("tb_Departments");
        }

然后运行下我们发现会出现如下错误:

image

原因是我们没有注册CreateInfo为complex 类型。所以我们首先需要注册CreateInfo为复合类型,在OnModelCreating中加上注册的代码:

modelBuilder.ComplexType<CreateInfo>();

我们可以看到运行后的数据库中:

image

总结

在这片文章中我们看到EF Code-First中如果自定义数据库结构,以及如何自动的Re-Build数据库。通过这两文章我们可以看到EF 在Development-Time上给我们带来了巨大的方便之处,也体会到EF越来越强大。

参考文献

Entity Framework 4 “Code-First”: Custom Database Schema Mapping