从EF的使用中探讨业务模型能否脱离单一存储层完全抽象存在

  上次赶时间,就很流水账地写了上次项目对EF的一次实践应用模式,因为太长了,也没能探讨太多,所以再继续扩展。

  这次想探讨的是,实体,如果作为类似于领域模型的业务模型存在,它的数据能否来自不同的数据源。这个想法首先是来自于这次应用中,Model First + 代码补充的方式形成了一个极好的效果。一方面满足了范式,减少了数据存储量;另一方面利用了封装特性,向业务提供了一个符合业务期望的实体。

首先看一个例子

  我用Model First建立了Account一个实体,实际生成的代码如下:

public partial class Account
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

  对应地,上面三个字段分别对应着数据库中的三个字段。

  然后,我再用Partial Class的方式,为Account进行扩充:

public partial class Account
{
    public string FullName
    {        get        {
          if (this._fullName == null)
          {
              this._fullName = String.Format("{0} {1}", this.FirstName, this.LastName);
          }
          return this._fullName;        }
    } string _fullName;
}

  

  这里就是关键了。此时,业务逻辑拿到的称之为Account的就不再是简单的DAO对象了,而是一个有着四个业务所需字段的业务模型对象。有兴趣的可以去看看我上一篇《Entity Framework 与 面向对象》中间设计模式的部分,里面讲到了为实体应用上了继承、多态、封装等面向对象的设计方式以达到业务模型所需的效果。

我的问题

  这种为Entity添加完整面向对象特性的方式,有着一种想法,那就是能否让一个Entity完全抽象架空于存储层,允许一个Entity的数据来自不同的数据源。

  首先,如果在存储层的视角来看,示例中Account的三个字段Id、FirstName、LastName来自于关系数据库,而FullName来自于计算值,也就是内存。站在数据库的角度上来说,FullName确实是不符合范式,所以很“多余”。

  如果从时间线来说,在实例化的时候,前三个数据库字段的数据就已经被加载了,而FullName是Lazy Load。

  但是,对于业务来说,他获得的不过是一个包含四个字段的Account的实例。

  那么我的问题就继续扩展了,一个业务模型,能不能将数据源完全封装,在业务获得该实体的时候,完全脱离关注实现?

  

  当我获得一个产品,那么这个产品的基本属性来自关系数据库,产品介绍来自NoSql,统计值来自动态计算。重要的是,这要是一个对象,而不是自行用多个对象拼装出来的

实际上,是封装的问题

  实际上,来到这里,就已经很明朗,这是一个封装的问题。我们从前遇到的是关系数据库和面向对象的阻抗失配,然后用ORM解决了。而今天,我们还可能遇到非强类型对象和非关系数据库以及强类型对象和关系数据库混合使用的问题,而且这使得其成为常态。

  通常,因为一个特性的原因,我们要在技术上进行选型。要么用静态语言,要么用动态语言。但是当出现一个用另一种方式更合适的时候,实现就变得很别扭了。

  比如用上面产品的问题,多少人是把产品详情作为整个文本值存在一个字段里呢?多少人又在用一张表来解决动态字段的问题呢?

实现,现实吗

  在Account的例子中,这种行为很容易实现。一方面依托于EF提供了相关的支持,另一方面是两个存储源具有时间上的关联。在进行一项业务的时候,所有数据库里,也就是存储在持久化存储器内的数据,最终都要读取到内存中才能被操作。这种纵向的关系,方面了应该来自于内存的数据源在产生数据的行为嵌入到整个业务过程中。

  但是当两个数据源没有纵向关系而是平行关系的时候,问题就来了。这个状况就跟当年的阻抗失配的问题类似。

  首先是一个迭代的问题。

  大家都知道,获取数据是有获取成本的。数据在抽象层面是“获取”,在实现层面是一次“拷贝”,拷贝的过程包括了“传输”。拷贝和传输就是数据获取的成本,这个成本在一些情形可以被很大的放大,比如从前的递归查询。

  如果不把递归写成SQL,那么在业务层面进行解决的话,就要往返很多次数据库获取数据。产生的业务结果是一样的,但产生的性能结果差异极大。

  而我假象的获取数据的行为是这样的:

  可以简单当两个数据源的时候,会存在一个“数据汇合”的问题,其实就是一个同步和匹配问题

  两个数据源获取到的数据需要匹配上,在一个大量查询的时候就变得很麻烦了。如果按照顺序进行匹配不就简单了?但是要知道,“顺序”是个很奇怪的命题,你查找到的数据是一个集合或者列表才有“顺序”,对于NoSQL一类Key-Value的形态,如何定义顺序呢?

  另外,如果是要一个数据源强行配合另一个数据源,那么一次数据获取行为的效率,就是由最慢的一个数据源决定的

  我再是想一下,如果是全部或者部分延迟加载,那么是不是说,读取数据都需要是异步的,而且合并数据的情况下,需要有一个用以合并数据的线程。

我打算尝试

  实际会遇到什么情况不好说,所以我倒是乐于去尝试一下。

  一开始的思路,是先尝试继续用扩充字段,然后把数据源获取封装好;然后我应该尝试去切入LinQ Provider,看看能不能在LinQ中下手,这对于.NET的使用或许更重要。

时间: 2024-08-24 14:07:58

从EF的使用中探讨业务模型能否脱离单一存储层完全抽象存在的相关文章

JVM并发机制的探讨——内存模型、内存可见性和指令重排序

[转]http://my.oschina.net/chihz/blog/58035 文章写的非常好,为作者点赞. JAVA内存模型 对于我们平时开发的业务应用来说,内存应该是访问速度最快的存储设备,对于频繁访问的数据,我们总是习惯把它们放到内存缓存中,有句话不是说么,缓存就像是清凉油,哪里有问题就抹一抹.但是CPU的运算速度比起内存的访问速度还要快几个量级,为了平衡这个差距,于是就专门为CPU引入了高速缓存,频繁使用的数据放到高速缓存当中,CPU在使用这些数据进行运算的时候就不必再去访问内存.但

需求分析之业务模型

数据和事件分开 先从Peter的数据和事件分开说起,Peter找了李福华讨论了返运的需求实现,他的建议是将库存和返运关系分离开来,即数据和事件分离开来:不要让(事件)状态污染数据,对于正常入库.调拨入库这属于原生态状态(Native Status)没问题,对于返运这种后天事件导致的状态就不要用来污染数据,而是单独页面承载操作,单独表结构来存储状态:我是深以为然:如果这样,出库是否也应该分离出来呢?库存表是否只是保存库存信息,表明库存还有多少多少,也属于"Native Status",我

BIEE入门(三)业务模型层

正如它的名字所示(Business Model and Mapping Layer),业务逻辑层需要把物理层的数据源以一种业务用户的视角来重新组织物理层的各个数据源(所谓的Mapping),同时在业务逻辑层里,我们将 需要真正构建数据仓库里的星型模型,包括: ·         事实表 ·         维表 ·         维表的层次结构(hierarchy) ·         事实表度量(measure)来提供一个模型供展现层使用,所以在业务逻辑层,用户需要同时具有技术的知识(数据仓

BW 业务模型关系与主数据取数

在接到业务需求之后,我认为重要的是理清楚自己该做什么.来实现业务.由于不了解业务,还是走了很多弯路.本可以不用这么做,还是这么做了.自然你最傻瓜的按照用户的方式去实现是没有问题的. 会使后面的人难以维护,可以精简的流程也变的复杂.冗余很多.那目前还不是我的层次,达不到.只能按照用户的想法去做. 因为是BW ON HANA 系统.能在BW 里将数据处理好 就在BW, 在HANA 视图里做简单的JOIN  . WEBI 里复杂的逻辑判断做展示.没有什么绝对.看那个好做.我所掌握大体如此. BW 里是

EF三种数据库操作模型比较

https://blog.csdn.net/xiongmeiqin/article/details/80196089 EF 中 Code First 的数据迁移以及创建视图 写在前面: EF 中 Code First 的数据迁移网上有很多资料,我这份并没什么特别.Code First 创建视图网上也有很多资料,但好像很麻烦,而且亲测好像是无效的方法(可能是我太笨,没搞成功),我摸索出了一种简单有效的方法,这里分享给大家. EF是Entity Framework(实体框架)的简写,是微软出品的用来

EF数据迁移(当模型改变时更新数据库)

https://msdn.microsoft.com/zh-CN/data/jj591621 Enable-Migrations Add-Migration 名称 Update-Database –Verbose

分析业务模型 类图

我们现在学习画类图,我使用的画图软件是processOn,首先我想我们自己要知道什么叫类?其实类就是对具有相同特性对象的封装组合. 这里我们也要知道类和对象的关系:类是对象的抽象,而对象是类的具体实例. 现在我们知道什么叫类,类和对对象的关系.下面我们就介绍这么画类图: 上面的是最简单的一个类图.下面我们说说类之间的关系: 分为3大类: 1.“直线”关系(我一般叫关联关系) (1).关联关系有很多关系,有一对一,一对多或者一对几   *号的意思表示0到多个  0..3  这里你要看清,有两个符号

浅谈云巴实时通信的编程模型

浅谈云巴实时通信的编程模型 中国物联网 2016-09-28 09:38 概要 有人常问,云巴实时通信系统到底提供了一种怎样的服务,与其他提供推送或 IM 服务的厂商有何本质区别.其实,从技术角度分析,云巴与其它同类厂商都是面向开发者的通信服务,宏观的编程模型都是大同小异,真正差异则聚焦于产品定位,业务模式,基础技术水平等诸多细节上.本文暂不讨论具体产品形态上的差异,着重从技术角度浅谈实时通信的编程模型. 什么是实时通信 「实时」(realtime) 一词在语义层面上隐含着对时间的约束(real

论软件工程

论软件工程 昨天一位同学问我对软件工程的体会?当时愣住了一下,不知道该怎么回答,感觉话到嘴边却不知道怎么表达,因为这个话题比较沉重,不知道该怎么用简短的语言来进行描述,要说可能一天都说不完,可能是自己的表达能力有限,语文没学好(高考语文不到80分),当时只是给出了:"这叫我怎么回答"这样的答案.随后在我的脑海里一直回忆自己开发经历,想从中找到一些信息.第一次听到软件工程是大三的时候有一门课程叫做软件工程,我依稀记得里面几个关键词语:髙聚类.低耦合.可扩展性.可行性.可维护性,同时还包括