导读:所谓的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的更多相关文章

  1. webpack 教程 那些事儿04-webpack项目实战分析

    这节主要讲解真正项目用用到的 webpack配置问题,项目实战篇 就像我们不会完全做一个项目,不用别人的轮子一样.这个配置我们借用 vue-cli 搭建的配置来研究,因为它已经足够优秀. 有了前面的基 ...

  2. 【无私分享:ASP.NET CORE 项目实战(第二章)】添加EF上下文对象,添加接口、实现类以及无处不在的依赖注入(DI)

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 上一章,我们介绍了安装和新建控制器.视图,这一章我们来创建个数据模型,并且添加接口和实现类. 添加EF上下文对象 按照我们以前 ...

  3. 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 ...

  4. 分享我们项目中基于EF事务机制的架构

    写在前面: 1. 本文中单元测试用到的数据库,在执行测试之前,会被清空,即使用空数据库. 2. 本文中的单元测试都是正确通过的. 要理解EF的事务机制,首先要理解这2个类:TransactionSco ...

  5. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式 进行本次文章之前,我们可能需要补充一些 ...

  6. Spark大型项目实战:电商用户行为分析大数据平台

    本项目主要讲解了一套应用于互联网电商企业中,使用Java.Spark等技术开发的大数据统计分析平台,对电商网站的各种用户行为(访问行为.页面跳转行为.购物行为.广告点击行为等)进行复杂的分析.用统计分 ...

  7. Asp.net MVC + EF + Spring.Net 项目实践3

    Asp.net MVC + EF + Spring.Net 项目实践 这一篇要整合Model层和Repository层,提供一个统一的操作entity的接口层,代码下载地址(博客园上传不了10M以上的 ...

  8. Asp.net MVC + EF + Spring.Net 项目实践(目录)

    用4篇博客来搭一个MVC的框架,可能对初学者会有一些帮助,大家共勉吧.我觉得对于中小型项目,这个框架可能还是有一定的用处的,希望能够帮助到一些人. Asp.net MVC + EF + Spring. ...

  9. 分享我们项目中基于EF事务机制的架构 【转载】

    http://www.cnblogs.com/leotsai/p/how-to-use-entity-framework-transaction-scope.html 写在前面: 1. 本文中单元测试 ...

随机推荐

  1. Hadoop学习3--安装ssh服务

    题前语:为什么要安装这个东西呢? 是因为我们要在多台机器之间通信,这个服务就相当于支持这种通信的一个桥梁,打个比喻,相当于windows里,通过远程桌面连接到其他机器. 所以,安装这个服务,的目的是: ...

  2. 原生js 用正则实现removeclass hasclass getsclass addclass .

    function getByClass(oParent,sClass){ if(oParent.getElementsByClassName){ return oParent.getElementsB ...

  3. 黄聪:VPS实现自动定时备份网站数据以及Mysql数据库到百度云同步盘

    建站多了,备份成了头疼的问题,因为你不知道你的VPS什么时候会宕机或者服务商跑路,一旦网站数据丢失,那么相当于前功尽弃了,所以自己研究出了一套自动备份的方法. 需要的东西: 1.一个VPS(虚拟空间没 ...

  4. JQuery 常用方法基础教程

    本文转自(http://www.cnblogs.com/Leo_wl/archive/2010/06/22/1762401.html) 对于学习使用jquery 的朋友,能用的到,简单的了解下jque ...

  5. C#学习笔记三: C#2.0泛型 可控类型 匿名方法和迭代器

    前言 C#1.0的委托特性使方法作为其他方法的参数来传递,而C#2.0 中提出的泛型特性则使类型可以被参数化,从而不必再为不同的类型提供特殊版本的实现方法.另外C#2.0还提出了可空类型,匿名方法和迭 ...

  6. Maven打包web工程成WAR

    其实不一定要通过Goals:package来打war包,直接run as maven bulid也行:

  7. PLSQL_基础系列01_正则表达REGEXP_LIKE / SUBSTR / INSTR / REPLACE(案例)

    2014-11-30 Created By BaoXinjian

  8. Java中类的加载、连接和初始化

    Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多 ...

  9. 程序进入 EXPORT App_Fault_ISR的原因及措施:

    最近再UCOSIII+LPC1768上移植modbus,在定时器初始化部分竟然跑飞进入 EXPORT  App_Fault_ISR,查资料.逛论坛.问大牛都没有解决,最后发现竟然是犹豫一个低级失误引起 ...

  10. Java多线程之新类库中的构件DelayQueue

    DelayQueue 是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走.这种队列是有序的,即队头对象的延迟到期时间最长.注意:不 ...