这是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. Windows Self Signed Driver

    In particular, Microsoft® instituted a device driver certification process for its Windows® desktop ...

  2. FluentData官方文档翻译

    开始 要求 .NET 4.0. 支持的数据库 MS SQL Server using the native .NET driver. MS SQL Azure using the native .NE ...

  3. Asp.net使用jQuery实现数据绑定与分页

    使用jQuery来实现Gridview, Repeater等服务器端数据展示控件的数据绑定和分页.本文的关注重点是数据如何实现数据绑定. Content jQuery的强大和可用性使得其迅速的流行起来 ...

  4. php计算脚本执行时间

    利用PHP的microtime实现 function getCurrentTime () { list ($msec, $sec) = explode(" ", microtime ...

  5. BZOJ 1295: [SCOI2009]最长距离 spfa

    1295: [SCOI2009]最长距离 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1295 Description windy有一块 ...

  6. TCP具体解释(2):三次握手与四次挥手

    TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接,就好像你给别人打电话.必须等线路接通了.对方拿 ...

  7. 当调用List Remove 失效时 [C#] .

    有没有试过从一个集合里面移除一个对象之后,这个集合仍然留有这个对象?世界之大,无奇不有.稍有疏忽,便会导致这种奇怪的现象.现在让我们看看这个“不死”对象究竟是怎么一回事. 1.“不死”对象现身 这个问 ...

  8. docker(4):coreos+docker+rancher真厉害

    http://blog.csdn.net/freewebsys/article/category/3103827

  9. 分布式缓存技术redis学习(二)——详细讲解redis数据结构(内存模型)以及常用命令

    Redis数据类型 与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多,常用的数据类型主要有五种:String.List.Hash.Set和Sor ...

  10. Remoting

    一.      Remoting基础 什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式.从微软的产品角度来看,可以说Remoting就是DCOM的一种升级,它改善了很多功能,并极 ...