asp.net-mvc - 用于检查 linq to sql 数据上下文中的唯一性的通用验证属性

标签 asp.net-mvc linq-to-sql data-annotations

我已经编写 ASP.NET 几天了。这是一个我什至无法自己弄清楚的问题。

我希望从代码中可以清楚地看出我想要完成的任务,而且我已经完成了,但这并不漂亮。此外,我想在任何表、任何字段上使用它,即根据我指定的表和字段检查值的唯一性,将其全部传递到属性构造函数中。

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);
    }
}

最佳答案

这刚刚来自 asp.net forums布拉德·威尔逊着。对此很满意。没有错误处理!

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);
}

关于asp.net-mvc - 用于检查 linq to sql 数据上下文中的唯一性的通用验证属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2031547/

相关文章:

asp.net-mvc - 在每个 Visual Studio 应用程序发布上重置 IIS 应用程序池标识权限

linq - 基于组合框值构建动态LINQ查询

c# - Linq to Sql 强制排序依据

c# - 用于验证确认密码的数据注释

c# - 自定义验证未执行

c# - ASP.NET MVC 绑定(bind)十进制值

asp.net-mvc - ASP.NET MVC 可以生成具有小写名称和 id 属性的元素吗

c# - 在 Razor 中将 css 与 c# mvc 混合

c# - 如何从 SQL to Linq 中的存储过程中进行选择

.net - 更改、覆盖、替换、asp.net MVC 3 默认 DataAnnotations 所需值和无效值的验证消息