Проверка для метода уникальных свойств - PullRequest
1 голос
/ 05 апреля 2011

Я пытался написать метод для вызова из CustomValidator, чтобы определить, является ли строковое свойство уникальным или нет.Я пытался сделать его универсальным, чтобы я мог повторно использовать код для множества различных строковых свойств.Я использую отражение.Это кажется слишком сложным способом сделать это?Есть ли лучший способ сделать это, но сделать его универсальным?

public virtual bool IsPropertyUnique(T entity, string newValue, string propertyName)
        {
            var values =
                Context.GetTable<T>.Where(e => string.Equals(e.GetType().GetProperty(propertyName).GetValue(e, null), newValue)).ToList();

            return values.Count == 0;
        }

Ответы [ 2 ]

0 голосов
/ 05 апреля 2011

Поскольку это LINQ to SQL, вам нужно предоставить что-то, что он сможет понять и проанализировать в SQL.В настоящий момент он увидит кучу сумасшедших размышлений и начнет плакать.

Вы можете изменить форму вызова вашего метода на

public Exists(Expression<Func<T, bool>> filter)
{
     return Context.GetTable<T>.Any(filter);
}

// Usage
string valueToCheck = "Boo!";
bool exists = Exists(t => t.Bar == valueToCheck);
if (exists)
{
    return "BAD USER - PICK SOMETHING UNIQUE";
}

, и это будет работать отлично.

Если вы хотите сохранить сигнатуру вашего метода, вы должны разбираться с деревьями выражений.По сути, вы хотите создать следующее выражение, чтобы LINQ to SQL мог идти: «о да, это условие where в столбце, которое соответствует свойству 'Bar'"

t => t.Bar == valueToCheck

Для воссоздания вам потребуется выполнитьследующее

private static Expression<Func<T, bool>> GetPredicate(string property, string value)
{
    // First you need a parameter of the correct type
    ParameterExpression parameter = Expression.Parameter(typeof (T), "t");

    // Then use that parameter to access the appropriate property
    MemberExpression propertyToAccess = Expression.Property(parameter, typeof (T), property);

    // Introduce the constant value to check
    ConstantExpression valueToCompare = Expression.Constant(value);

    // Make sure they're equal
    Expression comparison = Expression.Equal(propertyToAccess, valueToCompare);

    // and create the expression based on the method body and the parameter...
    return (Expression<Func<T, bool>>)Expression.Lambda(comparison, parameter);
}

public IsPropertyUnique(T entity, string property, string value)
{
    return !Context.GetTable<T>.Any(GetPredicate(property, value));
}

Также использование Any вместо Where может быть немного более производительным, поскольку ему не нужно загружать соответствующие записи из БД (вместо этого он просто выполняет IF EXISTS).

0 голосов
/ 05 апреля 2011

Одно из возможных улучшений:

public virtual bool IsPropertyUnique(T entity, string newValue, string propertyName)
{
    var propertyInfo = typeof(t).GetProperty(propertyName);
    return !FindAll()
           .Any(e => string.Equals(propertyInfo.GetValue(e, null), newValue));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...