我之前就写过一篇《实现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. JavaFX結合 JDBC, Servlet, Swing, Google Map及動態產生比例圖 (2):JavaFX建立及程式碼說明 (转帖)

    說明:就如同標題一樣,前端會用到JavaFX.Swing.Java Web Start.Google Map 的技術, 後端就是JDBC.Servlet的技術,以及我們會簽署認證jar檔案,這樣才可存 ...

  2. 使用Ivy管理项目中的依赖

    Ivy是什么 Ivy是一个跟踪管理项目直接以来关系的工具.Ivy具有良好的灵活性和可配置性,使其可以适应各种不同的依赖管理和构建过程要求:虽然Ivy作为依赖管理工具,其可以与Apache Ant进行紧 ...

  3. Xamarin.Android之MvvmCross

    欢迎大家加入以下开源社区 Xamarin-Cn:https://github.com/Xamarin-Cn Mvvmcross-Cn:https://github.com/Mvvmcross-Cn  ...

  4. HTML目录生成工具

    目录 内容简介 工具代码 使用方法 工具改进 内容简介 园子里面很多博主都会为自己的博文创建目录,方便大家浏览.我很好奇大家是怎么做的,是不是有自动生成目录的工具可以推荐一下(我知道word可以,但是 ...

  5. js模版引擎handlebars.js实用教程——each-循环中使用this

    返回目录 <!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content=" ...

  6. 阿里云主机(aliyun-Linux) x64安装Redis详解

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/97.html?1455870336 如何在Linux​上安装Redis呢, ...

  7. MVVM架构~mvc,mvp,mvvm大话开篇

    返回目录 百度百科的定义: MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示.作为一种新 ...

  8. Docker镜像

    docker镜像123? 额,由于没有实验环境,没有亲手实践,因此理解可能有不对的地方. 反正也是学习笔记,以后再修改吧... docker的镜像跟virtualbox的镜像不一样.在虚拟机中,镜像是 ...

  9. Atitti 跨语言异常的转换抛出 java js

    Atitti 跨语言异常的转换抛出 java js 异常的转换,直接反序列化为json对象e对象即可.. Js.没有完整的e机制,可以参考java的实现一个stack层次机制的e对象即可.. 抛出Ru ...

  10. Atitit paip.对象方法的实现原理与本质.txt

    Atitit paip.对象方法的实现原理与本质.txt 对象方法是如何实现的1 数组,对象,字典1 对象方法是如何实现的 这显然是一个对象方法调用.但对象方法是如何实现的呢?在静态语言中,因为有编译 ...