在一个LINQ to SQL的数据上下文检查的唯一性的一般属性验证 [英] A general validation attribute for checking uniqueness in a linq to sql data context

查看:112
本文介绍了在一个LINQ to SQL的数据上下文检查的唯一性的一般属性验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直对哦,一两天编程现在asp.net。这里有一个问题,我甚至不能开始找出自己。

我希望这是从code什么,我想完成显而易见的,我有,但它不是pretty。此外,我想用它在任何表,哪个领域,即检查对一个表和字段我指定一个值的唯一性,这一切都将通过该属性的构造函数。

 公共类UniqueEmailAttribute:ValidationAttribute
{
    公共UniqueEmailAttribute()
    {
    }    公众覆盖布尔的IsValid(对象的值)
    {
        //没有pretty。 TODO:废除与此有关。
        变种DB =新CoinDataContext();
        INT C = db.Emails.Count(E => e.Email1 == value.ToString());
        回报(布尔)(C == 0);
    }
}


解决方案

这是刚从的」> asp.net论坛。所以满意。没有错误处理!

 使用系统;
使用System.ComponentModel.DataAnnotations;
使用System.Data.Linq程序;
使用System.Linq的;
使用System.Linq.Ex pressions;
使用的System.Reflection;公共类UniqueAttribute:ValidationAttribute {
    公共UniqueAttribute(类型dataContextType,类型的EntityType,字符串propertyName的){
        DataContextType = dataContextType;
        的EntityType =的EntityType;
        属性名= propertyName的;
    }    公共类型DataContextType {搞定;私人集; }    公共类型的EntityType {搞定;私人集; }    公共字符串属性名{获得;私人集; }    公众覆盖BOOL的IsValid(对象的值){
        //构造数据上下文
        ConstructorInfo构造= DataContextType.GetConstructor(新类型[0]);
        DataContext的的DataContext =(DataContext的)constructor.Invoke(新对象[0]​​);        //获取表
        ITable表= dataContext.GetTable(的EntityType);        //获取属性
        的PropertyInfo的PropertyInfo = EntityType.GetProperty(属性名);        //我们的最终目标是一个前pression:
        //实体=> entity.PropertyName ==价值        //防爆pression:值
        反对convertedValue = Convert.ChangeType(值,propertyInfo.PropertyType);
        ConstantEx pression RHS =前pression.Constant(co​​nvertedValue);        //防爆pression:实体
        ParameterEx pression参数=前pression.Parameter(的EntityType实体);        //防爆pression:entity.PropertyName
        MemberEx pression财产=前pression.MakeMemberAccess(参数的PropertyInfo);        //防爆pression:entity.PropertyName ==价值
        BinaryEx pression等于=前pression.Equal(财产,右轴);        //防爆pression:实体=> entity.PropertyName ==价值
        LambdaEx pression波长=前pression.Lambda(相等,参数);        //实例与正确的TSource(我们的实体类型)的计数方法
        MethodInfo的countMethod = QueryableCountMethod.MakeGenericMethod(的EntityType);        //执行count(),并说:你是有效的,如果你有没有匹配
        诠释计数=(int)的countMethod.Invoke(空,新的对象[] {表,拉姆达});
        返回计数== 0;
    }    //获取Queryable.Count< TSource>(IQueryable的< TSource>中前pression<&Func键LT; TSource,布尔>>)
    。私有静态MethodInfo的QueryableCountMethod = typeof运算(可查询).GetMethods()第一(M => m.Name ==计数&放大器;&安培; m.GetParameters()长度== 2);
}

I've been programming asp.net for, oh, a couple of days now. Here's a question I can't even begin to figure out for myself.

I hope it's obvious from the code what I want to accomplish, and I have, but it's not pretty. Furthermore I'd like to use it on whatever table, whatever field, i.e. check the uniqueness of a value against a table and field I specify, passing it all into the attribute constructor.

public class UniqueEmailAttribute : ValidationAttribute
{
    public UniqueEmailAttribute()
    {
    }

    public override Boolean IsValid(Object value)
    {
        //not pretty. todo: do away with this.
        var db = new CoinDataContext();
        int c = db.Emails.Count(e => e.Email1 == value.ToString());
        return (Boolean) (c == 0);
    }
}

解决方案

This just in from asp.net forums by Brad Wilson. So pleased with it. No error handling!

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Linq;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

public class UniqueAttribute : ValidationAttribute {
    public UniqueAttribute(Type dataContextType, Type entityType, string propertyName) {
        DataContextType = dataContextType;
        EntityType = entityType;
        PropertyName = propertyName;
    }

    public Type DataContextType { get; private set; }

    public Type EntityType { get; private set; }

    public string PropertyName { get; private set; }

    public override bool IsValid(object value) {
        // Construct the data context
        ConstructorInfo constructor = DataContextType.GetConstructor(new Type[0]);
        DataContext dataContext = (DataContext)constructor.Invoke(new object[0]);

        // Get the table
        ITable table = dataContext.GetTable(EntityType);

        // Get the property
        PropertyInfo propertyInfo = EntityType.GetProperty(PropertyName);

        // Our ultimate goal is an expression of:
        //   "entity => entity.PropertyName == value"

        // Expression: "value"
        object convertedValue = Convert.ChangeType(value, propertyInfo.PropertyType);
        ConstantExpression rhs = Expression.Constant(convertedValue);

        // Expression: "entity"
        ParameterExpression parameter = Expression.Parameter(EntityType, "entity");

        // Expression: "entity.PropertyName"
        MemberExpression property = Expression.MakeMemberAccess(parameter, propertyInfo);

        // Expression: "entity.PropertyName == value"
        BinaryExpression equal = Expression.Equal(property, rhs);

        // Expression: "entity => entity.PropertyName == value"
        LambdaExpression lambda = Expression.Lambda(equal, parameter);

        // Instantiate the count method with the right TSource (our entity type)
        MethodInfo countMethod = QueryableCountMethod.MakeGenericMethod(EntityType);

        // Execute Count() and say "you're valid if you have none matching"
        int count = (int)countMethod.Invoke(null, new object[] { table, lambda });
        return count == 0;
    }

    // Gets Queryable.Count<TSource>(IQueryable<TSource>, Expression<Func<TSource, bool>>)
    private static MethodInfo QueryableCountMethod = typeof(Queryable).GetMethods().First(m => m.Name == "Count" && m.GetParameters().Length == 2);
}

这篇关于在一个LINQ to SQL的数据上下文检查的唯一性的一般属性验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆