导读:所谓的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. PHP 打印调用函数入口地址(堆栈)

    今天网站出现一个BUG,然后直接在数据库类里面写日志,看是哪条SQL出了问题,SQL语句到是找到了,但是不知道这条SQL语句来自何处,于是就想啊,如果能有一个办法,查看当前正在运行的这个方法是被哪个方 ...

  2. xubuntu手记

    一. xfce下intelij快捷键冲突 window manager 快捷键 keyboard快捷键

  3. HDU 2176 取(m堆)石子游戏(Nim)

    取(m堆)石子游戏 题意: Problem Description m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,1 ...

  4. JavaScript笔记之数组 keyword(存储和释放&堆栈 & 按值 引用)

    1.数组创建及初始化 var obj=new Array(); var arr=[]; 可以延伸为长度一定的,字面量定义数组 2.堆栈 按值传递 引用类型 数组是引用类型,不是值传递, 栈:系桶自动分 ...

  5. laravel 删除一条migration后要执行composer命令

    Laravel 删除一条migration 字数29 阅读30 评论0 喜欢0 如果迁移已经执行,先回滚php artisan migrate:rollback 然后删除迁移文件,运行composer ...

  6. Android之BroadcastReceiver 监听系统广播

    绑定广播有两种方式 一.配置文件绑定,在程序未启动也能监听 二.代码方式绑定,在程序启动后才能监听 1.绑定和取消绑定广播 public class MainActivity extends Acti ...

  7. 使用Visual Studio 2013 调试 MASM 汇编程序!

    原文地址:http://kipirvine.com/asm/debug/vstudio2013/index.htm Using the Microsoft Visual Studio 2013 Deb ...

  8. bootstrap-按钮组、字体图标

    字体图标: <div class="container"> <div class="row"> <span class=" ...

  9. substr

    substr(string,start,length) string - 指定的要截取的字符串 start - 必需,规定在字符串的何处开始 正数 - 在字符串的指定位置开始 负数 - 在从字符串结尾 ...

  10. codeblocks安装后无法编译

    codeblocks安装后无法编译: 解决办法: 1.下载自带编译器的codeblock安装包. 2.安装完后.修改配置 (1)打开软件,选择setting->Compiler (2)在编译器设 ...