EF7 Code First Only-所引发的一些“臆想”

At TechEd North America we were excited to announce our plans for EF7, and even demo some very early features. This post will cover the announcements we made during the session. You can also watch the recorded session from TechEd (the EF7 content starts at 46:40). When watching the demos please bear in mind that this is a very early preview - not all the features shown are even submitted into the main code base yet.
以上文字说明来自:EF7 - New Platforms, New Data Stores
没错,微软已经在北美发布了 EF7(应该只是演示、代码甚至都未提交到版本库),时间是 2014-05-19,而我却前几天才看到这篇文章,都过了大半年时间了,哎!
有时候程序员学习新技能,首先了解一下此技能的“性格”和“脾气”,看适不适合自己,就像找对象一样,不适合的话,霸王硬上弓是没用的,那如果合适的话,就好好的了解她、善待她,而不要整天再去想一些其他的(见一个爱一个的不少),“红杏出墙”的最后结果是:到头来什么都没得到。编程语言、编程技术等一些相关的东西,往往是更新速度很快,但也造成了一些“迷惑性”,就像你瞒着女朋友上街看美女一样,守住自己的本心,适合自己,老婆不在多,一个就好。
言归正传,我个人觉得这次 EF7 的发布,就像之前的 ASP.NET vNext 发布一样,是一个里程碑,或者说因为 ASP.NET vNext,所以 Entity Framework 必须要做一些适合“她”的改变,其实追溯到底,他们都是微软下一代 ASP.NET 的组成部分,那 EF7 具体的改变是什么呢?她适不适合你呢?我们先来看一下两个关键词:
- New Platforms(新平台):之前发布的 ASP.NET vNext,已经支持跨平台了,先试想一样:单独的 Entity Framework 应用程序可以运行吗?或者说 Entity Framework 可以独立存在吗?答案当然是不可以,也就是说 Entity Framework 必须依附于某一类应用程序,比如 Windows Forms、ASP.NET 等,既然 Entity Framework 的“宿主”已经支持跨平台了,那 Entity Framework 就没有不支持的道理,给力的一段话是:EF7 will work on all of these platforms as well as Mono, on both Mac and Linux. 请注意关键字“all”,听起来是蛮激动人心的。
- New Data Stores(新数据存储):新数据存储是什么?EF7 we will be enabling providers that target non-relational data stores,注意关键字“provider,non-relational”,难道是支持 NoSQL?但文中并没有提到这个关键字,反而提到一个什么 Azure Table Storage?完全没有听说过,这个可以看作是微软给自己打广告,就像针对新平台的视频演示中使用 Windows Phone 一样,见怪不怪了。
因为之前 ASP.NET vNext 的发布,其实这两点内容现在看来 EF7 也“理应如此”,但如果单纯去看 Entity Framework 的发展历程,你会发现这两点改变是非常巨大的,以前的 Entity Framework 只是“循规蹈矩”做好 ORM 份内的工作就好,而这一次完全像脱胎换骨一样,当然有人喜欢,也有人感觉讨厌,除了上面讲到的两个改变关键词,EF7 另一个改变就是:
- Code First Only:EF7 - What Does “Code First Only” Really Mean
这篇文章是前几天无意看到的,本来是想翻译一下分享出来的,但奈何英文功力实在太差,翻译到一半就翻译不下去了。Code First 不是我们第一次遇到,从 EF 4.1 版本,Entity Framework 就开始支持 Code First 了,以至于我们在现有 Entity Framework 的最新版本 6. 1 中,可以很好的使用 Code First 模式,当然你也可以使用 Database & Model First 模式,但在 EF7 中,请注意标题的关键字“Only”,也就是说 EF7 将只支持 Code First 模式,这是个什么概念呢?微软到底想干嘛?
别激动,我们先来说下 Code First 的兄长-Database & Model First 模式,这也是我们使用 Entity Framework 的常用模式,我们开发一个应用程序,首先根据业务需求去设计表结构,当然这个工作是业务需求人员和 DBA 去完成的,和程序员相关不大,等数据库表结构什么的确定下来以后,然后我们程序员就开始使用 Entity Framework 根据已有数据库生成对应模型了,大致体现是:

如果在应用程序开发过程中,需求变更了,业务需求人员就会反馈至 DBA,DBA 就会根据业务需求变化修改表结构等,然后就对程序员说:XXX表结构已改。程序员收到数据库修改完成指令后,就开始进行下面操作:

“从数据库生成模型”后,我们针对原来模型写的一些业务方法就必须要做出调整,然后我们就进行重写,重写,再重写。。。
以上是我们使用 Database & Model First 模式的常规开发过程,我相信你肯定深有体会,画了一个简单示意图:

这种模式可以很清楚的看到是以数据库为核心,所有的程序设计、代码编写都是依赖于数据库,数据库一变,那什么都得跟着调整。在这个过程中,Entity Framework 变成了什么?我觉得仅仅是替代我们编写 SQL 代码的工具而已,并没有发挥它的强大之处,ORM 中的 “O”,代表的是 Object(对象),但在这种模式开发的应用中,你会发现这些对象只不过是充满属性集合的类,我们做一些业务简单的应用是可以的,但当开发一些业务极其复杂的应用,按照这种 Database & Model First 模式,大部分的业务都会写在数据库中,比如用存储过程去实现,而对于程序员来说,只需要调用一个数据库接口即可,那还不如直接写 SQL 代码来的方便,以至于 Entity Framework 在这种场景下变成了“鸡肋”,我觉得在 EF7 之前的版本,是微软对开发者做出的一种妥协,就像“从数据库生成模型”这个方式一样,只不过是微软想把你从“事务脚本模式”拉出来,所做出的第一步,之后 EF4.1(开始支持 Code First)是第二步,现在的 EF7(仅支持 Code First)是第三步,这是最重要的一步,也是里程碑的一步,如果在上面应用场景中使用的是 EF7,那将会变成什么呢?请看下面示意图:

你会发现,现在和之前的模式是完全“逆向”的,“Code First Only”模式代表着什么?说白了就是,如果你使用 EF7,那你就必须使用 Code First 模式,不要再想着“从数据库生成模型”了,一切数据库生成操作都必须体现在代码中,这是你的工作,你可能觉得这种思想有点“迎合”领域驱动设计,其实从 EF 4.1 开始使用 Code First,我个人觉得微软已经开始进行改变了,只不过现在改变的更加彻底,至于所蕴含的意义,只能意会了,我现在表达不出来,也许过几年你会发现一切都是理所当然。
如果你使用 Entity Framework,并一直使用的是 Code First 模式,其实 EF7 带给你的变化并不多(除了上面关键字的两点),下面我简单谈一下我自己使用 EF Code First 的一般过程,当然也是我个人非常喜欢的,首先开发一个应用程序,我们一般先设计这个应用程序所存在的模型(Model),这个模型应该不受任何“污染”,也就是说它只是一个单纯的模型,不要在上面加一些配置相关的东西,比如什么 Required、MaxLength 等属性,这个应该是属于数据存储相关的东西,不应该在模型中存在,所以我们应该保持它的“纯净”,然后在模型中专注于业务的实现,这个其实就是领域驱动设计的部分体现,我想这也是以后应用程序开发的最普通过程,当然前提是以后(谁也说不准),贴一下示例模型代码:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Age { get; set; }
public string Address { get; set; }
public DateTime DateAdded { get; set; }
public virtual Role Role { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateAdded { get; set; }
}
这段代码胡乱摘自之前博文,模型中除了不要放配置相关的东西之外,还有一点就是,在设计对象关联的时候,尽量用对象进行关联,比如 User 中的 Role 属性,如果在之前的设计中,肯定会设计成 RoleId,你如果觉得设计成 Role 对象属性,那数据库中该怎么存储啊?其实如果你有这个想法,那你还是有点受“数据库驱动模式”开发的影响,在模型中应该不要去关注数据存储的一些东西,而应该把设计重点放在业务的实现上,这一点很重要,至于其他你所担心的东西,Entity Framework 都会帮你完成,比如上面模型中,你不需要进行任何配置,使用 EF Code First,他会自动帮你生成相应数据库,User 和 Role 的关联,在数据库中是用 RoleId 表示,但你发现 User 对象中并没有 RoleId,而只有 Role 属性,但当你使用 EF 获取 User 对象,访问其 Role 属性的时候,你可以访问到 Role 对象中的所有属性,也就是说,你在写代码的时候,只需要关注模型的设计即可,其他的你不用关心,一切都有 Entity Framework 呢,至于模型内的一些操作都是对象之间的操作,就像现实生活中我与你对话一般。
另外,还需要提一点是,如果模型对象是多对多关系,比如上面的 User 和 Role,有可能是一个 User 拥有多个 Role,而一个 Role 也可能对应多个 User,那模型该怎么实现呢?其实很简单:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Age { get; set; }
public string Address { get; set; }
public DateTime DateAdded { get; set; }
public virtual IList<Role> Roles { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateAdded { get; set; }
public virtual IList<User> Users { get; set; }
}
我们分别给两个对象加了两个集合属性,这也非常符合现实场景,那你所关心的数据库该怎么实现呢?其实你使用 EF Code First 不需要任何配置,它会自动帮你生成三个表:User、Role 和 UserRole,具体关联我就不说了,在对象访问的时候,你会感受不到数据库的“存在”,一切似乎都非常智能,说多了没用,自己体会才是真理。
我喜欢的 Code First 模式是:模型是干净的(不包含任何配置),也更智能化(用对象进行关联),至于数据库映射配置,可以单独去实现,比如上面多对多关联映射的自定义示例代码:
public class UserRoleDbContext : DbContext
{
public UserRoleDbContext()
: base("name=UserRoleDb")
{
//this.Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Role> Role { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Configurations
.Add(new UserConfiguration())
.Add(new RoleConfiguration());
base.OnModelCreating(modelBuilder);
}
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
HasKey(c => c.Id);
Property(c => c.Id)
.IsRequired()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(t => t.Roles)
.WithMany(t => t.Users)
.Map(m =>
{
m.ToTable("UserRole");
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
});
}
}
public class RoleConfiguration : EntityTypeConfiguration<Role>
{
public RoleConfiguration()
{
HasKey(c => c.Id);
Property(c => c.Id)
.IsRequired()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
}
EF7 符不符合我们的口味?它能给我们带来什么?能改变我们什么?现在说的都是一些“空头支票”,一切只能用时间来证明。
最后分享一个非常棒的文章,也存在我书签很久了,作者是一个 MVP (关键是女的),我觉得她的一些想法和我有一些共鸣,详细内容不说了,大家可以自行体会,关键词:DDD、Entity Framework,文章链接:数据点 - 领域驱动设计的编码:数据聚焦型开发的技巧
EF7 Code First Only-所引发的一些“臆想”的更多相关文章
- asp.net core 使用EF7 Code First 创建数据库,同时使用命令创建数据库
1.首先下载vs2015的Asp.Net Core(RC2)的插件工具(https://www.microsoft.com/net/core#windows)2.创建一个asp.net Core的项目 ...
- 由“RangeError: Invalid status code: 0”错误所引发的思考
最近发现一个基于Node.js平台上的Express框架运行的Web网站经常报这样一个错误: RangeError: Invalid status code: 网站的源码中有专门针对错误处理的中间件, ...
- 爱与恨的抉择:ASP.NET 5+EntityFramework 7
EF7 的纠缠 ASP.NET 5 的无助 忘不了你的好 一开始列出的这个博文大纲,让我想到了很久之前的一篇博文:恋爱虽易,相处不易:当EntityFramework爱上AutoMapper,只不过这 ...
- EntityFramework 7 开发纪录
博文目录: 暂时开发模式 Code First 具体体现 DbContext 配置 Entity 映射关联配置 Migration 问题纪录(已解决) 之前的一篇博文:EF7 Code First O ...
- ASP.NET 5+EntityFramework 7
爱与恨的抉择:ASP.NET 5+EntityFramework 7 EF7 的纠缠 ASP.NET 5 的无助 忘不了你的好 一开始列出的这个博文大纲,让我想到了很久之前的一篇博文:恋爱虽易,相 ...
- .Net Core 杂记
在学习.net core的路上,遇到很多坑,慢慢了解了.net core设计理念和设计思想(纯属跟人理解). 再此整理了之前写的一些学习笔记,后续也会把新的学习新的加上. 1..net core 跨平 ...
- EntityFramework 7 Linq Contains In 奇怪问题(已修复)
问题说明: 博客问题纪录 Use EF7, Linq Contains In is error. EF7 Code Commit adding (client side) support for Co ...
- EntityFramework 7 Join Count LongCount 奇怪问题(已修复)
问题说明: 博客问题纪录 Use EF7, Linq Join Count is error EF7 Code Commit EF7 版本(注意 rc): 旧版本:"EntityFramew ...
- chapter8_4 错误处理
在Lua中,对于大多数程序都不用作任何错误处理,应用程序本身会负责这类问题. 所有的Lua活动都是由应用程序的一次调用开始的,这类调用要求Lua执行一个程序块. 执行过程中发生了错误,此调用会返回一个 ...
随机推荐
- centos7 搭建nginx和tomcat集成
一.安装jdk 1.yum install jdk 2.安装好了之后配置环境变量 在/etc/profile 二.创建项目运行目录 1. 我放在home目录 mkdir /web/webapps ...
- MySQL Can't connect to MySQL server on 'localhost' (10061)
run > services.msc > rightclick MySQL > properties >start 搞定
- phpexcel读取excel的xls xlsx csv格式
我之前写过一篇PHP读取csv文件的内容 上代码index.php <?php /** * * @author XC * */ class Excel { public $currentShee ...
- Ubantu 下安装 tensorflow
# 在 Linux 上: $ sudo apt-get install python-pip python-dev python-virtualenv $ virtualenv --system-si ...
- aspnet_isapi.dll设置图文介绍.net的程序实现伪静态
用URLRewriter控件 ①:首先要有这个文件URLRewriter.dll,如果没有,赶快到网上下载一个,并将其放到下面的bin目录里面,并且将其引用添加到下面里面; ②:下面就是Web.Con ...
- Android内存泄漏分享
内容概述 内存泄漏和内存管理相关基础. Android中的内存使用. 内存分析工具和实践. 以下内容不考虑非引用类型的数据,或者将其等同为对应的引用类型看待--一切皆对象. 内存泄漏概念 不再使用的对 ...
- 一步步学习javascript基础篇(2):作用域和作用域链
作用域和作用域链 js的语法用法非常的灵活,且稍不注意就踩坑.这集来分析下作用域和作用域链.我们且从几道题目入手,您可以试着在心里猜想着答案. 问题一. if (true) { var str = & ...
- 备忘-Sql server Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置
select * from sysprocesses where dbid= db_id('数据库名') 通过此语句可查看目前所有的连接进程 不够了就必须设置Max Pool Size,理论最大值为3 ...
- [转]各种移动GPU压缩纹理的使用方法
介绍了各种移动设备所使用的GPU,以及各个GPU所支持的压缩纹理的格式和使用方法.1. 移动GPU大全 目前移动市场的GPU主要有四大厂商系列:1)Imagination Technologies的P ...
- android内部培训视频_第三节 常用控件(Button,TextView,EditText,AutocompleteTextView)
第三节:常用控件 一.Button 需要掌握的属性: 1.可切换的背景 2.9.png使用 3.按钮点击事件 1) onClick 3) 匿名类 4) 公共类 二.TextView 常用属性 1.a ...