这是Model的第二篇,上一篇点这里

这块完全是扒了@何镇汐大神博客里的教程实现的,在这之前完全没想到数据验证居然可以这样做!!在此表示严重感谢!!!

点击这里可以去了解这个方法的原理,老胡估计自己是完全说不清楚的了。http://www.cnblogs.com/xiadao521/p/4111815.html

还是来图上看

Validation部分,这里是从@何镇汐教程中拔过来的代码,

老胡只是在_BaseEntityValidation类里面进行了简单的集成进来。

 namespace CAMCOCO.Model.Core.Entity
{
using System.Collections.Generic;
using Validation; public partial class _BaseEntityValidation
{
private readonly List<IValidationRule> _validationRules;
private ValidationHandler _validationHandler; protected _BaseEntityValidation()
{
_validationRules = new List<IValidationRule>();
_validationHandler = new ValidationHandler();
} public override void Dispose()
{
base.Dispose();
_validationRules.Clear();
} /// <summary>
/// 为实体对象添加一条验证规则
/// </summary>
/// <param name="rule">验证规则</param>
public void addValidationRule(IValidationRule rule)
{
if (rule != null)
{
_validationRules.Add(rule);
}
} /// <summary>
/// 对实体对象进行合法性验证,如果验证失败,将通过throw Exception进行抛出
/// </summary>
public void validate()
{
IValidationResultCollection results = getValidationResult();
_validationHandler.handle(results);
} private IValidationResultCollection getValidationResult()
{
IValidationResultCollection result = ValidationFactory.createValidationor().validate(this);
foreach (var rule in _validationRules)
result.addResult(rule.validate());
return result;
} }
}

有了这个神器,在业务逻辑层里实现数据验证简直就是一种享受。

下面是在业务层调用的时候的代码样子:

 public void addPopedomGroup(PopedomGroup obj)
{
try
{
IRepository<PopedomGroup> res = createRepository<PopedomGroup>(); PopedomGroup dbObj = PopedomGroupFactory.createPopedomGroup();
dbObj.cloneFromWithProperties(obj, "Name", "IsHidden");
dbObj.Order.Index = createNewOrderIndex<PopedomGroup>(); dbObj.addValidationRule(new PopedomGroupCannotExistsSameNameRule(res, dbObj));
dbObj.validate();
res.add(dbObj);
commit();
}
catch (Exception ex)
{
throw ex;
}
}
dbObj.addValidationRule(new PopedomGroupCannotExistsSameNameRule(res, dbObj));

这句代码可以很方便地在本次逻辑操作中加入任何的验证条件,而验证规则的编写也很简单,同时可以实现任意组合

例如:

 namespace CAMCOCO.Business.Authentication.Rule
{
using System.ComponentModel.DataAnnotations;
using CAMCOCO.Business.Core.Rule;
using CAMCOCO.Model.Core.Validation;
using CAMCOCO.Data;
using CAMCOCO.Model.Authentication.Entity; public class PopedomGroupCannotExistsSameNameRule : BaseRule<PopedomGroup>
{
public PopedomGroupCannotExistsSameNameRule(IRepository<PopedomGroup> res, PopedomGroup checkObj)
: base(res, checkObj)
{ } public override ValidationResult validate()
{
ValidationResult result = ValidationResult.Success;
if (_res.exists(m => m.Id != _checkObj.Id && m.System.DeleteFlag == false && m.Name == _checkObj.Name))
{
result = createValidationResult("PopedomGroup", "权限组名称不能重复");
}
return result;
}
}
}

OK,到此为止,老胡的实体模型基类基本就搭建完毕了,在老胡的架构里,所有的实体类都必须从三大基类(BaseEntityNormal, BaseEntityOrder, BaseEntityTree)派生而来,具备如下一些特性:

1、所有的实体都有唯一的一个ID号。

其实这个问题展开来还有一系列的考虑,在之前的项目经验中,我采用过两种形式的ID,一种是数据库自增标识,一种是Guid。两种方式分别都有自己的优点,自增标识属于数据库自主管理,我们写代码的时候不同进行维护,同时所有ID号都是连续的,优点是方便记忆,能够快速定位数据,够直观。同时缺点也是明显的,由于自增特性,我们没法手工任意修改,当需要做数据迁移或者在系统之间导入导出数据时,这个东西很麻烦,你得先建立一个临时表用于记录新老ID对应记录等等,同时因为其是连续的数字,如果在安全验证上出现漏洞,很容易就被用户调取到不属于自身范围的数据。而GUID正好解决以上两个问题,同时GUID带来的问题就是无法记忆无法推算,在开发及测试程序时无法很好地预判结果和肉眼查找数据。

在老胡做这个架构的时候,两种方案都尝试了,最终为了保留EF中的某些重要特性,比如GUID模式通过EF无法自动生成符合老胡要求的主键,我希望数据的保存依托ID作为主键同时是一个聚集索引,但GUID明显不适合做聚集索引。手工制表的时候老胡一般都是吧GUID作为主键,然后去掉聚集索引,将聚集索引建立在数据创建时间字段上。

2、所有实体都会记录下创建时间;

3、所有实体都是逻辑删除;

4、Order类实体可以通过框架标准接口进行排序;

5、Tree类实体可以通过框架标准接口进行排序操作和节点操作;

6、所有实体都具备完整的自我合法性验证功能;

7、实体模型可以被业务层及以上的任意层使用,但以为除了业务层意外均不掌握修改实体的方法,所以实体数据的安全性得到了保障,要修改实体内容,只能通过业务层;

8、通过EntityBuilder建造者来初始化实体基类信息,派生类中不用关心其基类部分的属性该如何赋值;

BaseFilter的特性:

1、凡是有查询需求的实体,都因为为其构造Filter,而这些Filter都必须派生自BaseFilter;

2、BaseFilter中已经将实体基类中的标准属性进行了定义,派生类中只需要针对派生实体的特定属性进行特定扩展即可;

3、Filter本身不应该有任何操作功能,只是一堆属性定义(和贫血实体一样);

4、Filter的目的是取代查询函数里的一大堆参数而存在的

 //普通查询接口
IQueryable<Entity> findEntityList(long id, string searchName, int maxThanAge, ...); //采用Filter模式
class EntityFilter{
public int Id{get;set;}
public string searchName{get;set;}
public int maxThanAge{get;set;}
//...
} IQueryable<Entity> findEntityList(EntityFilter filter);

这是Model的第二篇,上一篇点这里

[CAMCOCO][C#]我的系统架构.服务器端.(四)----Model层 实体的自我验证的更多相关文章

  1. [CAMCOCO][C#]我的系统架构.服务器端.(三)----Model层

    我估计一片帖子写不完这个,慢慢来吧... 先上个图,按照图来说明应该容易说清楚一些. 在Model Core核心代码中,老胡创建了一个类 CAMCOCO.Model.Core,要求今后在Model L ...

  2. [CAMCOCO][C#]我的系统架构.服务器端.(二)----DATA层

    这一层在园子里有很多很多的介绍了,这层写好之后老胡也没多研究,基本上就是参考的园子里大咖们的写法,具体的说明老胡也细说不了了,把接口和思路简单描述一下就好,如果有问题还是那句话,感谢您不吝赐教,老胡这 ...

  3. [CAMCOCO][C#]我的系统架构.服务器端.(一)

    尽量少的前言 虽然写了N年代码了,但总觉得什么东西都是囫囵吞枣,无法尽得其精髓.最近整理了一套心目中的架构,如有错误之处,烦劳不吝指正,老胡在此不胜感激!! 第一篇 我心目中的架构 做了无数个系统,写 ...

  4. [CAMCOCO][C#]我的系统架构 总图

    之前写的感觉有点乱,把架构的设计图先放上来吧,对照着说. CAMCOCO架构能够支持的模型: 1.B/S程序,比如CRM什么的,和访问普通网站没什么区别,都是从WEB服务器上进行操作: 2.APP的服 ...

  5. iOS 系统架构及常用框架(iOS的系统架构分为四个层次)

    1.iOS基于UNIX系统,因此从系统的稳定性上来说它要比其他操作系统的产品好很多 2.iOS的系统架构分为四层,由上到下一次为:可触摸层(Cocoa Touch layer).媒体层(Media l ...

  6. Android系统架构说明介绍

    Android系统架构说明介绍 Android系统架构和一些普遍的操作系统差不多,都是采用了分层的架构,从他们之间的架构图看,Android系统架构分为四个层,从高层到低层分别是应用程序层.应用程序框 ...

  7. 高级java高并发,高性能,分布式,高可用,负载均衡,系统架构实战

    java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战 视频课程包含: ...

  8. iOS 系统架构

    https://developer.apple.com/library/ios/documentation/Miscellaneous/Conceptual/iPhoneOSTechOverview/ ...

  9. iOS系统架构

    1.iOS系统架构 iOS的系统架构分为四个层次 核心操作系统层 (Core OS) 它包括 内存管理 , 文件系统 , 电源管理以及一些其他的操作系统任务, 它可以直接和硬件设备进行交互 核心服务层 ...

随机推荐

  1. C#利用SharpZipLib解压或压缩文件夹实例操作

    最近要做一个项目涉及到C#中压缩与解压缩的问题的解决方法,大家分享. 这里主要解决文件夹包含文件夹的解压缩问题. )下载SharpZipLib.dll,在http://www.icsharpcode. ...

  2. 【转】 Volley NegativeArraySizeException 解决

    http://blog.csdn.net/very_caiing/article/details/46241531 今天在百度统计看项目上有一个crash比较高的bug: Java.lang.Nega ...

  3. KVO机制

    KVO,全称为Key-Value Observing,是iOS中的一种设计模式,用来监测对象的某些属性的实时变化情况并作出响应 首先,假设我们的目标是在一个UITableViewController内 ...

  4. cocos2d jsb 打包 Android APK

    1.首先要会普通的cpp 打包成Android APK 下面所说的是在cocos2d-x 2.2.2 或者 2.3 版本号中.本文在Eclipse总用ndk编译cocos2d-x. 老生常谈cocos ...

  5. Qt多线程学习:创建多线程

    [为什么要用多线程?] 传统的图形用户界面应用程序都仅仅有一个运行线程,而且一次仅仅运行一个操作.假设用户从用户界面中调用一个比較耗时的操作,当该操作正在运行时,用户界面一般会冻结而不再响应.这个问题 ...

  6. VirtualBox从USB设备(PE)启动

    cmd中执行 VBoxManage internalcommands createrawvmdk -filename E:\usb.vmdk -rawdisk \\.\PhysicalDrive1 - ...

  7. linux 内核参数VM调优 之 参数调节和场景分析

    1. pdflush刷新脏数据条件 (linux IO 内核参数调优 之 原理和参数介绍)上一章节讲述了IO内核调优介个重要参数参数. 总结可知cached中的脏数据满足如下几个条件中一个或者多个的时 ...

  8. redhat的启动方式和执行次序

    rc.d的内容如下: init.d/ :各种服务器和程序的二进制文件存放目录. rcx.d/: 各个启动级别的执行程序连接目录.里头的东西都是指向init.d/的一些软连接.具体的后边叙述. 还有三个 ...

  9. SQL SERVER-Delete和Truncate的区别

    背景:       一般在删除表数据时候,通常会有执行两个SQL语句:delete和truncate,有条件的删除我们平时都会用delete,而如果全部删除,那我们通常都会选择truncate,因为这 ...

  10. 读懂IL代码就这么简单

    原文地址:http://www.cnblogs.com/zery/p/3366175.html 一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不 ...