我之前就写过一篇《实现UniqueAttribute唯一性约束》,虽然实现了通过调用IsValid方法可以进行唯一性验证,但有一个缺点,那就是耦合度过高,原因是里面的DB上下文对象是直接写在里面的,如下:

public override Boolean IsValid(Object value)
{
bool validResult = false;
//TEMSContext 是我项目中的DB上下文类,这里是直接指定的,与TEMSContext 紧耦合,若需要实体与访问分离就会有问题!
using (TEMSContext context = new TEMSContext())
{
string sqlCmd=string.Format("select count(1) from [{0}] where [{1}]=@p0",tableName,filedName);
context.Database.Connection.Open();
var cmd=context.Database.Connection.CreateCommand();
cmd.CommandText = sqlCmd;
var p0 = cmd.CreateParameter();
p0.ParameterName = "@p0";
p0.Value = value;
cmd.Parameters.Add(p0);
int result=Convert.ToInt32(cmd.ExecuteScalar());
validResult=(result<=0);
}
return validResult;
}

现在为了解决这个问题,我目前采用的是通过属性注入DB上下文类型,然后再采取反射动态创建实例,这样就降低了依赖,完整代码如下:

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity; namespace Zwj.TEMS.Common
{
/// <summary>
/// 唯一性标识
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class UniqueAttribute : ValidationAttribute
{
protected string tableName;
protected string filedName; public Type ContextType { private get; set; } public UniqueAttribute(string tableName, string filedName)
{
this.tableName = tableName;
this.filedName = filedName;
} public override Boolean IsValid(Object value)
{
//如果是系统调用,就不会传入ContextType类型,所以此处就直接返回通过
if (this.ContextType == null)
{
return true;
} bool validResult = false;
using (DbContext context = ContextType.Assembly.CreateInstance(ContextType.FullName) as DbContext)
{
string sqlCmd = string.Format("select count(1) from [{0}] where [{1}]=@p0", tableName, filedName);
context.Database.Connection.Open();
var cmd = context.Database.Connection.CreateCommand();
cmd.CommandText = sqlCmd;
var p0 = cmd.CreateParameter();
p0.ParameterName = "@p0";
p0.Value = value;
cmd.Parameters.Add(p0);
int result = Convert.ToInt32(cmd.ExecuteScalar());
validResult = (result <= 0);
context.Database.Connection.Close();
}
return validResult;
}
}
}

这样虽然降低了对实际DB上下文的依赖,但新问题又出来了,就是如果通过手动来验证该特性(如下代码)就没有问题,但如是想让EF框架在RUD时能自动验证,则会出现问题,因为没有传入ContextType,所以也就无法进行验证,我想这也是微软之所以没有实现UniqueAttribute唯一性约束的原因吧,不知道哪位高手能指点一下,非常感谢!

以下是手动来验证该特性:

        public void ValidateEntity(object entity)
{
var t = entity.GetType();
var properties = t.GetProperties();
foreach (var p in properties)
{
UniqueAttribute[] attrs;
if (p.TryGetAttribute<UniqueAttribute>(out attrs))
{
attrs[0].ContextType=typeof(TEMSContext);
bool result = attrs[0].IsValid(p.GetValue(entity, null));
Assert.IsTrue(result, "验证不唯一,存在重复值!");
}
}
}

  

实现UniqueAttribute唯一性约束-优化版的更多相关文章

  1. 实现UniqueAttribute唯一性约束

    using System; using System.ComponentModel.DataAnnotations; using System.Data.Entity; namespace Zwj.T ...

  2. 实现UniqueAttribute唯一性约束,sqlunique约束[转]

    using System; using System.ComponentModel.DataAnnotations; using System.Data.Entity; namespace Zwj.T ...

  3. 通用PE工具箱 4.0精简优化版

    通用PE工具箱 4.0精简优化版 经用过不少 WinPE 系统,都不是很满意,普遍存在篡改主页.添加广告链接至收藏夹.未经允许安装推广软件等流氓行为,还集成了诸多不常用的工具,令人头疼不已.那么今天给 ...

  4. Constraint1:主键约束,唯一性约束和唯一索引

    1,主键约束创建索引 作为Primay Key的列是唯一的,非空的,Sql Server在创建主键约束时,自动为主键列创建一个唯一索引,并且索引列不允许为null. create table dbo. ...

  5. GHOST WIN7系统64位经典优化版 V2016年

    来自系统妈:http://www.xitongma.com 深度技术GHOST win7系统32,64位经典优化版 V2016年3月 系统概述 深度技术ghost win7系统64位经典优化版适用于笔 ...

  6. Chrome 扩展程序 CrxMouse 优化版 v3.0.1

    说明 CrxMouse 原版更新至 v2.7.8,跟进升级优化版至 v3.0.1. 改动说明: 1. 去除可能存在的后台数据上传隐患: 2. 解决鼠标右键拖动时的轨迹漂移问题. 3. 加入部分默认设置 ...

  7. sqlserver2005唯一性约束

    [转载]http://blog.163.com/rihui_7/blog/static/21228514320136193392749/ 1.设置字段为主键就是一种唯一性约束的方法,如   int p ...

  8. POJ-2533最长上升子序列(DP+二分)(优化版)

    Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41944   Acc ...

  9. mysql主键约束和唯一性约束

    主键约束和唯一性约束都是索引,它们的区别是: 主键字段可以确保唯一性,但主键字段不能为NULL. 唯一性约束可以确保唯一性,但唯一性约束的字段可以为NULL 唯一性约束对含有NULL的记录不起作用,即 ...

随机推荐

  1. Powershell--批量拆分SQL语句为事务并批处理

    作为DBA,时不时会遇到将数据导入到数据库的情况,假设业务或研发提供一个包含上百万行INSERT语句的脚本文件,而且这些INSERT 语句没有使用GO来进行批处理拆分,那么直接使用SQLCMD来执行会 ...

  2. zendframework 2

    我想我的生活需要新的挑战 zf2整个框架里面都应用了namespace,并且他的每个模块,我们都可以根据自己的需要去命名路径,对我来说,zf2的模块化更加的清晰,对于外包来说,或许很方便. 创建他,我 ...

  3. Linux cat命令

    200 ? "200px" : this.width)!important;} --> 介绍 cat命令经常会用来查看一个文件的内容,并且结合它本身的一些参数经常可以用来做一 ...

  4. 跟我一起云计算(4)——lucene

    了解lucene的基本概念 这一部分可以参考我以前写的博客: http://www.cnblogs.com/skyme/tag/lucene/ lucene是什么 下图是一个很好的说明: 1.luce ...

  5. [翻译]AKKA笔记 - LOGGING与测试ACTORS -2 (一)

    在前两章 ( 一 , 二 ) ,我们大致讲了Actor和message是怎么工作的,让我们看一下日志和测试我们的 TeacherActor . RECAP 这是上一节我们的Actor代码: class ...

  6. osgi 2

    基础的API BundleActivator  BundleContext ServiceReference HelloServiceFactory ServiceTracker osgi 疑惑: I ...

  7. Linux应用总结(1):自动删除n天前日志

    linux是一个很能自动产生文件的系统,日志.邮件.备份等.虽然现在硬盘廉价,我们可以有很多硬盘空间供这些文件浪费,让系统定时清理一些不需要的文件很有一种爽快的事情.不用你去每天惦记着是否需要清理日志 ...

  8. 《Wireshark数据包分析实战》 - http背后,tcp/ip抓包分析

    作为网络开发人员,使用fiddler无疑是最好的选择,方便易用功能强. 但是什么作为爱学习的同学,是不应该止步于http协议的,学习wireshark则可以满足这方面的需求.wireshark作为抓取 ...

  9. js获取当前时间显示在页面上

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. javascript设计模式与开发实践阅读笔记(5)——策略模式

    策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 我的理解就是把各种方法封装成函数,同时存在一个可以调用这些方法的公共函数.这样做的好处是可以消化掉内部的分支判断,使代码效率 ...