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

推荐订阅源

P
Privacy & Cybersecurity Law Blog
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
B
Blog RSS Feed
罗磊的独立博客
V
V2EX
V
Visual Studio Blog
博客园 - 叶小钗
W
WeLiveSecurity
小众软件
小众软件
K
Kaspersky official blog
美团技术团队
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
Recorded Future
Recorded Future
Project Zero
Project Zero
Hugging Face - Blog
Hugging Face - Blog
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
Microsoft Azure Blog
Microsoft Azure Blog
V
Vulnerabilities – Threatpost
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Forbes - Security
Forbes - Security
M
MIT News - Artificial intelligence
H
Hacker News: Front Page
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Spread Privacy
Spread Privacy
The Register - Security
The Register - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Google Online Security Blog
Google Online Security Blog
PCI Perspectives
PCI Perspectives
The Last Watchdog
The Last Watchdog
AI
AI
N
News | PayPal Newsroom
D
DataBreaches.Net
Cloudbric
Cloudbric
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog

博客园 - 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