【EF 5】结合项目实战分析EF三大工作模式之—Database First
导读:所谓的EF的Databasefirst工作模式,是目前我们(不涉及社会领域)用的最广的一种模式,也是本次ITOO开发所采用的工作模式。本篇博客,就分析在项目中通过Database First模式去实现多租户的一个过程。
一、DBFirst模式下的研究分析
先看这种模式下生成的各个文件:
说明:之所以通过EF可以实现对于数据库的操作,主要依靠两个文件:edmx(概念模型描述、存储模型描述、映射关系描述),实体对象类(DBFirst下的表一和表二类)
误区:改掉数据库连接串,则实现对连接数据库的操作。
说明:这种方法再DB模式下是完全失效的。它失效的原因,需要回归到ORM框架的工作原理去解释。我们有一个很重要的映射文件存在于edmx文件中,当我们更改数据库连接串时,通过配置文件读取到的映射文件,并不是连接串中的数据库。先看下面 例子:
上面的图片,是我在研究为什么改掉了数据库连接串还是无法实现对库读写操作的时候做的demon。OldModel,是我用最开始提供建库代码的模板数据库运用DBFrist模式创建的,NewModel,则是我使用通过代码生成的数据库创建的DBFrist模型。
有意思的是:打开这两个文件下的每一个文件,几乎全都是一样的,除了App.config里面的连接串不一样和应用程序中的web.config里面的连接串不一样。
所以,我们最初的解决方案是,直接在上下文中,即熟知的public partialclass TestCrateDatabaseEntities : DbContext
类,更改构造函数去实现App.config里面的连接,即:
我们试图通过这样的方式,去回避构造函数对于配置文件的读取,即:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><connectionStrings>
<add name="TestCrateDatabaseEntities"connectionString="metadata=res://*/DBFrist.csdl|res://*/DBFrist.ssdl|res://*/DBFrist.msl;provider=System.Data.SqlClient;providerconnection string="data source=ANGEL\ANGELSQLSERVER;initialcatalog=TestCrateDatabase;persist security info=True;userid=sa;password=xia0626;MultipleActiveResultSets=True;App=EntityFramework""providerName="System.Data.EntityClient" />
</connectionStrings></span>
但结果是:失败了。
二、原因思考
1,
ORM框架中的映射文件,在Code Firtst模式中,通过mapping类的形式出现,在DBFirst模式中,这个映射文件,去哪儿了?
2,
如果,我们的实体对象类完全一致,各个数据库,除了数据库名称不一样,表结构、字段等完全一致,为什么我们明明更改了数据库连接地址,依然失败了?
3,
除了数据库的连接地址,相同的数据库生成的DBFirst下的ADO数据模型,真的完全一致吗?
4,在web.config里面配置的连接,不更改可不可以?没有这个配置,又可不可以?
看上面例子中的区别(将edmx文件作为XML格式打开):
OldModel:
NewModel:
可以看出,这一关键的文件,表面上一致,事实上很多地方都不一样。我们虽然更改了数据库连接串,但对于edmx文件中的命名空间等对应关系,并没有更改。我们拿着新数据库的连接串 读取的却是最初生成代码的数据库的映射关系。所以,我们失败了!备注:在这个文件中有很多地方都存在命名空间,并不是圈出来的才是。另外在设计器中也有,但那个文件并不影响操作,具体原因请思考设计器的作用,和EF操作数据库的流程。
三、解决方案
第一个思路:
既然原因是由于edmx
的描述文件不一样,那就改成一样的:
方案一:
引入IO流,将edmx文件作为XML文件进行操作,先获取到已经存在于此文件的数据库命名,然后用新数据库名称去替换,然后重新写回edmx文件。(实现了对于新库的操作)
问题一:已存在数据库名称的获取(每次连接数据库时都将名称存入线程缓存里面),但是很多很多个用户操作系统,怎么办,怎么区分?
——废弃
解决方案:使用正则表达式,匹配指定字符串。原因:每个数据库的名称前半截的字符串都是一样的,只是后面6位企业号不一样。使用正则表达式完全可以匹配替换。(可以实现)
问题二:在DBFirst模式下,EF必须读取edmx文件,而edmx文件只有一个(可以由多个edmx文件共同描述一个对象,这里是针对多用户操作,而不是多表操作),那么当用户A在改这个文件的时候,用户B、C………同时操作数据库,怎么办?(以下解决方案,都未能最终证实,仅是理论上的想法和尝试)
解决方案一:程序在硬盘的级别是无法执行的,每个用户更改后的edmx文件,都存起来,在需要的时候,从内存读取。可是,这个读取的入口在哪里?在未被修改的上下文类中,通过构造函数,继承基类,再通过基类的构造函数去读取,那么,1,更改基类的构造函数(基类源码在分享资料中);2,不继承基类,直接在上下文类的构造函数中写。(还未进行测试)
第二个思路:
在java中,ORM框架的实现之一是Hibernate,在使用hibernate的时候,是通过一个XML文件手写映射关系,在.NET中,可不可以在edmx中,手写映射关系,去除掉具体的命名空间?????(未深入尝试,hibernate引入的dtd和edmx引入的schema有冲突,具体的协调方案还未研究出来)
第三个思路:
在edmx文件中,将所有涉及到具体数据库指向的值,都设置为变量(edmx文件的实质就是一个XML文件,可以用到XML文件的操作方式,基本上都可以用)。在读取映射文件之前,通过给变量赋值的方式,确定具体的数据库映射。
……
四、总结
思考:是否可以通过负载均衡去解决当前的高并发问题?????我认为是不能的。所以DBFirst留下的问题,都得继续研究测试。。。。。
【EF 5】结合项目实战分析EF三大工作模式之—Database First的更多相关文章
- webpack 教程 那些事儿04-webpack项目实战分析
这节主要讲解真正项目用用到的 webpack配置问题,项目实战篇 就像我们不会完全做一个项目,不用别人的轮子一样.这个配置我们借用 vue-cli 搭建的配置来研究,因为它已经足够优秀. 有了前面的基 ...
- 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)
目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...
- Asp.Net Core 2.0 项目实战(4)ADO.NET操作数据库封装、 EF Core操作及实例
Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...
- 分享我们项目中基于EF事务机制的架构
写在前面: 1. 本文中单元测试用到的数据库,在执行测试之前,会被清空,即使用空数据库. 2. 本文中的单元测试都是正确通过的. 要理解EF的事务机制,首先要理解这2个类:TransactionSco ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式 进行本次文章之前,我们可能需要补充一些 ...
- Spark大型项目实战:电商用户行为分析大数据平台
本项目主要讲解了一套应用于互联网电商企业中,使用Java.Spark等技术开发的大数据统计分析平台,对电商网站的各种用户行为(访问行为.页面跳转行为.购物行为.广告点击行为等)进行复杂的分析.用统计分 ...
- Asp.net MVC + EF + Spring.Net 项目实践3
Asp.net MVC + EF + Spring.Net 项目实践 这一篇要整合Model层和Repository层,提供一个统一的操作entity的接口层,代码下载地址(博客园上传不了10M以上的 ...
- Asp.net MVC + EF + Spring.Net 项目实践(目录)
用4篇博客来搭一个MVC的框架,可能对初学者会有一些帮助,大家共勉吧.我觉得对于中小型项目,这个框架可能还是有一定的用处的,希望能够帮助到一些人. Asp.net MVC + EF + Spring. ...
- 分享我们项目中基于EF事务机制的架构 【转载】
http://www.cnblogs.com/leotsai/p/how-to-use-entity-framework-transaction-scope.html 写在前面: 1. 本文中单元测试 ...
随机推荐
- 如何刪除GitHub中的repository
如何刪除一github中的repository,這本該是個非常簡單的操作,可一開始搜的時候,有不少文章比較含糊.這裡就記錄下來吧. 1.訪問https://github.com/settings/pr ...
- ConcurrentHashMap使用要点
ConcurrentHashMap的简要总结: 1.public V get(Object key)不涉及到锁,也就是说获得对象时没有使用锁: 2.put.remove方法要使用锁,但并不一定有锁争用 ...
- Python进阶07 函数对象
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函数也是一个对象 ...
- svn: Can't convert string from 'UTF-8' to native encoding 的解决办法
http://www.leakon.com/archives/610 http://www.toplee.com/blog/566.html http://svnbook.red-bean.com/e ...
- Opencv 2.4.9在Ubuntu下的配置与安装
[原]Opencv 2.4.9在Ubuntu下的配置安装 Opencv 2.4.9在Ubuntu下的配置与安装 surgewong@gmail.com http://blog.csdn.net/su ...
- Sql Server Text 类型列 查询和更新
Text(ntext.image)类型为大数据字段,因为存储方式不同,也决定了其查询和更新不同于一般方法. 1.表定义: 2.查询: Like查询是可用的: select * from dbo.nod ...
- 基于NPOI的Execl导入导出例子
源地址:http://bbs.csdn.net/topics/390830774
- oracle 导入数据
1.在数据库中建立实例数据库之后,运行cmd 2.键入 imp空格(实例数据库名)/(实例数据库口令)空格file=“拖入数据地址” 比如czt.dmp文件直接拖进去(空格)full=y 3.按ent ...
- mysql 非安装版的一个自动安装脚本及工具(更新版)
http://blog.csdn.net/iihero/article/details/5596401
- 编写一个go gRPC的服务
前置条件: 获取 gRPC-go 源码 $ go get google.golang.org/grpc 简单例子的源码位置: $ cd $GOPATH/src/google.golang.org/gr ...