架构模式对象与关系结构模式之:标识域(Identity Field)

时间:2022-08-28 11:58:11

一:标识域(Identity Field)

标识域(Identity Field)可以理解为主键。使用领域模型和行数据入口的时候,就要使用标识域,因为这两个对象代表的是唯一存在的那个数据记录。事务脚本、表模块、表数据入口等就不需要这个映射。

public abstract class DomainObj
{
    public string Id {get; set;}

public string Name {get; set;}
    protected UnitOfWork uow = new UnitOfWork();
    protected void MakeNew()
    {
        uow.RegisterNew(this);
    }
    protected void MakeDirty()
    {
        uow.RegisterDirty(this);
    }
    protected void MakeRemoved()
    {
        uow.RegisterRemoved(this);
    }
}

二:外键映射(Foreign Key Mapping)

所谓 外键映射 就是在获取对象的时候,把对象中的属性对象的值也获取到。我们在 延迟加载 中,使用的就是这一技术。这是 UserMap 中的一段代码,显示了如何将 组织 和 用户 以及用户所在的班级集合(一个用户可能存在于多个班级中) 一起进行获取到:

public override User AbstractFind(string id)
{
    var user = base.AbstractFind(id);
    if( user == null )
    {
        //
        string sql = @"
        DECLARE @ORGID VARCHAR(32)='', @TRAINNINGS VARCHAR(MAX)='';
        SELECT @ORGID=OrganizationId,@TRAINNINGS=TrainingIds FROM [EL_Organization].[USER] WHERE ID=@Id
        SELECT * FROM [EL_Organization].[USER] WHERE ID=@Id
        SELECT * FROM [EL_Organization].[ORGANIZATION] WHERE ID=@ORGID
        SELECT * FROM [EL_Organization].[Training] WHERE CHARINDEX(ID + ',', @TRAINNINGS + ',') > 0";
        var pms = new SqlParameter[]
        {
            new SqlParameter("@Id", id)
        };
        var ds = SqlHelper.ExecuteDataset(CommandType.Text, sql, pms);
        user = DataTableHelper.ToList<User>(ds.Tables[0]).FirstOrDefault();
        user.Organization =  DataTableHelper.ToList<Organization>(ds.Tables[1]).FirstOrDefault();
        user.Trainnings =  DataTableHelper.ToList<Trainning>(ds.Tables[2]).ToList();
        if(user == null)
        {
            return null;
        }

user = Load(user);
        // 注意,除了 Load User 还需要 Load Organization
        user.Organization = Load(user.Organization) as Organization;
        foreach(var t in user.Trainnings)
        {
            Load(t);
        }
        return user;
    }
    return user;
}

三:依赖映射(Dependent Mapping)

依赖映射的表现形式就是:依赖着本身没有数据映射器,其所有操作数据库的行为都发生在所有者中间。

依赖者没有标识域(当然,这并不意味着数据库中它就一定没有主键)。依赖者与值对象很像,或者说,从 C# 的语法的角度而言,它们没有区别。

四:嵌入值(Embedded Value)

指领域模型中用到的那些小对象,它们对数据库没有意义,对领域对象却有意义。

五:升级版的标识映射

如果表示映射不是仅仅一个字段该怎么办,我们需要考虑多个字段,下面是一个标识映射的升级版本,查看:

public class Key : IEquatable<Key>
{
    private object[] fields;

private string domainType;

public Key(string id, Type type)
        : this(new[] { id }, type.ToString())
    {

}

public Key(object[] fields, string domainType)
    {
        if (string.IsNullOrEmpty(domainType))
            throw new ArgumentNullException("domainType can not be null");

CheckKeyNotNull(fields);
        this.fields = fields;
        this.domainType = domainType;
    }

private void CheckKeyNotNull(object[] fields)
    {
        if (fields == null)
        {
            throw new ArgumentNullException("Can not have a null key");
        }

foreach (var field in fields)
        {
            if (field == null)
            {
                throw new ArgumentNullException("Can not have a null element of key");
            }
        }
    }

private void CheckSingleKey()
    {
        if (fields.Length > 1)
        {
            throw new ArgumentException("Can not take value on composite key");
        }
    }

public string GetId()
    {
        CheckSingleKey();
        return fields[0].ToString();
    }

public override bool Equals(object obj)
    {
        if (obj == null) return false;
        if (object.ReferenceEquals(this, obj)) return true;
        if (this.GetType() != obj.GetType()) return false;
        return Equals(obj as Key);
    }

public bool Equals(Key other)
    {
        if (this.fields.Length != other.fields.Length)
        {
            return false;
        }

for (int i = 0; i < fields.Length; i++)
        {
            if (!fields[i].Equals(other.fields[i]))
            {
                return false;
            }
        }

if (this.domainType != other.domainType)
        {
            return false;
        }

return true;
    }

public override int GetHashCode()
    {
        int hash = 0;

for (int i = 0; i < fields.Length; i++)
        {
            hash += fields[i].GetHashCode();
        }

hash += this.domainType.GetHashCode();
        return hash;
    }
}

代码不再多议。

架构模式对象与关系结构模式之:标识域(Identity Field)的更多相关文章

  1. Design Mode 之 结构模式

    这里我们主要介绍7种结构型模式:适配器模式.装饰模式.代理模式.外观模式.桥接模式.组合模式.享元模式.其中对象的适配器模式是各种模式的起源,我们看下面的图: B1.适配器模式(Adapter) 模式 ...

  2. node&lpar;3&rpar;MVC代码结构模式moogoDB的学习

    ---恢复内容开始--- 一.MVC代码结构模式 设计模式:观察者模式.中介者模式,这种模式,主要做的事情是处理类与类之间‘高内聚.低耦合’; 代码架构模式:MVC.MVVM.MVP Model:模型 ...

  3. Java设计模式之结构模式

    一.外观模式 分析:外观模式是为子系统的一组接口提供一个统一的界面,数据库JDBC连接应用就是外观模式的一个典型例子,特点:降低系统的复杂度,增加灵活性.结果:代码示例: public class D ...

  4. 七个结构模式之装饰者模式&lpar;Decorator Pattern&rpar;

    定义: 使用组合的方法,动态给一个类增加一些额外的功能,避免因为使用子类继承而导致类继承结构复杂.并且可以保持和被装饰者同一个抽象接口,从而使客户端透明. 结构图: Component:抽象构件类,定 ...

  5. 七个结构模式之组合模式&lpar;Composite Pattern&rpar;

    定义: 组合多个对象形成树形结构来表示"整体-部分"关系的层次结构,其中的叶子对象和容器对象具有相同的接口,可以使用抽象类来进行管理. 结构图: Component:抽象构件类,对 ...

  6. &lbrack;JAVA设计模式&rsqb;第三部分:结构模式

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. php设计模式&lpar;二&rpar;:结构模式

    上一篇我们介绍了设计模式的特性并且详细讲解了4种创建型模式,创建型模式是负责如何产生对象实例的,现在我们继续来给大家介绍结构型模式. 一.什么是结构型模式? 结构型模式是解析类和对象的内部结构和外部组 ...

  8. APP 自动化测试封装结构模式

    原文出处http://www.toutiao.com/a6268089772108333314/ 做过UI自动化测试同学,都会深深体会几个痛点:维护量大.适配量大.编写代码巨大等.基于这些问题,大家都 ...

  9. 十二、结构模式之门面(Facade)模式

    什么是门面模式 门面模式(也有翻译为外观模式)是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面进行.其为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子 ...

随机推荐

  1. MVC项目中ExecutionTimeout不生效的解决方案

    我们做web服务器端开发时,经常会遇到一个需求场景,因为某些耗时处理造成页面的响应处理时间超长,技术角度就想能否给页面处理程序一个指定的超时时间,服务端处理程序执行时间超过这个指定的超时时间则中断处理 ...

  2. Hibernate的save&lpar;&rpar;和persist&lpar;&rpar;的区别

    hibernate之所以提供与save()功能几乎完全类似的persist()方法,一方面是为了照顾JPA的用法习惯.另一方面,save()和 persist()方法还有一个区别:使用 save() ...

  3. OCJP&lpar;1Z0-851&rpar; 模拟题分析(三)over

    Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...

  4. p ython笔记第一天

    一.Linux基础 - 计算机以及日后我们开发的程序防止的服务器的简单操作 二.Python开发 http://www.cnblogs.com/wupeiqi/articles/5433893.htm ...

  5. CentOS上安装MongoDB速记

    测试环境版本CentOS 6.5 先创建安装目标文件夹并进入至该文件夹: mkdir /opt/mongodb cd /opt/mongodb 给mongodb创建用户及用户组: groupadd m ...

  6. 对于 url encode decode js 和 c&num; 有差异

    在js对一个值进行解码使用:decodeURIComponent,编码使用:encodeURIComponent

  7. MySQL慢查询语句的定位

    使用以下语句可以查询相关的配置和日志所在位置: show variables like '%slow%'; 名词解释: log_slow_admin_statements: 打开后可以将一些比较慢的管 ...

  8. url参数&plus;,&amp&semi;,&equals;,&sol;等转义编码

    url出现了有+,空格,/,?,%,#,&,= 等特殊符号的时候,可能在服务器端无法获得正确的参数值. 案例: <img src="BarCode39.aspx?barcode ...

  9. ARCSDE直连Oracle时出现错误Failed to connect to the specified server&period; Underlying DBMS error&lbrack;ORA-12154&colon; TNS&colon;could not resolve the connect identifier specified&period; No extended error&rsqb;

    买了新笔记本,装软件. 在ARCSDE直连Oracle时遇到问题. esri官网给的解释是因为安装arcgis时安装目录里有特殊字符(详见:https://support.esri.com/en/te ...

  10. PHP获取本周的每一天的时间

    1.PHP获取未来一周的时间 public function getWeek() { for($i=0;$i<7;$i++) { $arr[$i]=date('Y-m-d',strtotime( ...