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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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上下文类型,然后再采取反射动态创建实例,这样就降低了依赖,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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;
        <strong>public Type ContextType { private getset; }
        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;
        }
    }
}
</strong>

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void ValidateEntity(object entity)
{
    var t = entity.GetType();
    var properties = t.GetProperties();
    foreach (var 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, "验证不唯一,存在重复值!");
        }
    }
}

  

本文转自 梦在旅途 博客园博客,原文链接: http://www.cnblogs.com/zuowj/p/4397943.html ,如需转载请自行联系原作者

实现UniqueAttribute唯一性约束-优化版相关推荐

  1. 解决数据库报唯一性约束错误的实践

    猿们好,我是honery,今天来给大家唠一唠如何避免数据库报唯一性约束的错误. 一.问题的引出   首先抛出一个问题,如何保证数据库表中的某列的值都不一样呢?相信大家很容易想到给该列加上唯一性约束,这 ...

  2. 主键约束、唯一性约束、唯一索引

    1.主键约束(PRIMARY KEY) 1) 主键用于唯一地标识表中的每一条记录,可以定义一列或多列为主键. 2) 是不可能(或很难)更新. 3) 主键列上没有任何两行具有相同值(即重复值),不允许空 ...

  3. mysql中主键约束和唯一约束的区别_主键约束和唯一性约束的区别

    1.主键约束(PRIMARY KEY) 1) 主键用于唯一地标识表中的每一条记录,可以定义一列或多列为主键. 2) 是不可能(或很难)更新. 3) 主键列上没有任何两行具有相同值(即重复值),不允许空 ...

  4. YOLO3升级优化版!Poly-YOLO:支持实例分割!

    YOLO3升级优化版!Poly-YOLO:支持实例分割! POLY-YOLO: HIGHER SPEED, MORE PRECISE DETECTION AND INSTANCE SEGMENTATI ...

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

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

  6. Oracle之唯一性约束(UNIQUE Constraint)使用方法具体解释

    Oracle | PL/SQL唯一索引(Unique Constraint)使用方法 1 目标 用演示样例演示怎样创建.删除.禁用和使用唯一性约束. 2 什么是唯一性约束? 唯一性约束指表中一个字段或 ...

  7. 智能&大数据时代,架构师思维的十个学习步骤(优化版)

    前言: 秦朝的<书同文.车同轨>,加上唐朝的<诗同形>,有效的减法设计,创造了大一统(加法)的辉煌国度.君不见,在前面各步骤里,诸如:从复杂中设计出简单.以需求检验设计等都是基 ...

  8. 47. 对数组进行冒泡排序,实现冒泡排序的基础版与优化版

    //冒泡排序: //优化版口诀:序而不排 -> 优化原理:证实已经有序,不需要再次循环 -> 代码角度实现优化:内重循环已证实有序,外重循环不需要再次循环可以停止了.建立flag标记告诉外 ...

  9. mysql 唯一性约束报错_怪异的MySQL Online DDL报错Duplicate entry

    今天线上执行Online DDL的时候发现一个奇怪的报错,觉得比较意义,遂整理如下.线上数据库版本:percona server 5.7.14 报错现场:每次执行的时候重复报错记录都不一样 mysql ...

最新文章

  1. 聊聊并发(三)——JAVA线程池的分析和使用
  2. 攻防世界base除4_CCTV5周末看点:周六!女足世界杯1/4决赛连战三场;周日!中超15轮国安碰鲁能...
  3. BeetleX.Http.Clients访问https服务
  4. arduino 舵机接线图_用fritzing绘制arduino硬件连线图
  5. 如何经营一家培训机构?
  6. 论Web控件开发 - 完美上传下载控件“新”(一)
  7. 2018辛苦一年了,程序员这样跟大boss谈2019加薪,谈薪杯具变喜剧
  8. 插件使用 之 Bmap
  9. LightOj 1336(Sigma Function)
  10. java之调用七牛云接口完成视频加水印
  11. PHP资源汇总-内容包括模板、框架、数据库、安全等方面的库和工具
  12. javaMail(javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection)
  13. Mac小技巧—如何查看 Mac 的关机和重启历史
  14. yii2 aliases web.php,Yii2的深入学习--别名(Aliases),yii2aliases
  15. 编码、学习、玩耍一条龙,这是我看过最良心的「游戏编程」网站,没有之一!...
  16. Redis缓存过期策略
  17. TITAN RTX 与 RTX 3090 参数的对比,探计单双精度的问题
  18. 清北学堂 2017-10-05
  19. 痛心!又一中产家庭倒下,为什么我建议你不要轻易买保险?
  20. java段落对齐_Java 设置Word段落缩进、对齐方式

热门文章

  1. ogg批量配置_Mac批量文件重命名A Better Finder Rename11.07直装
  2. HEVC官方代码下载及码流分析软件使用
  3. 剑指offer面试题[15]-链表中倒数第K个结点
  4. 启动服务提示-bash: mongod: command not found
  5. mysql数据库随机生成数据库_MySQL 从零开始:08 番外:随机生成数据库数据
  6. android 第三方裁剪,Android裁剪意向不适用于系统图库应用程序,但适用于第三方应用程序...
  7. ios 搭建php,超级签名网源码+ios分发+签名端本地化+文字搭建教程_PHP源码
  8. layui tree ajax刷新,layer 刷新某个页面的实现方法
  9. 计算机vf知识点总结,计算机等级考试二级VF常用函数总结
  10. java 中特殊的_Java中一些特殊关键字