Селектор недвижимости и где <T>Запрос с использованием Linq - PullRequest
4 голосов
/ 16 ноября 2011

Я пытаюсь сделать это:

public class SomeEntityClass
{
    public Guid MyClassProperty {get;set;}
}

public class AnotherEntityClass
{
    public Guid AnotherProperty {get;set;}
}

public T GetByProperty<T>(Guid value, Expression<Func<T, object>> selector)
{
    return = Session.Query<T>().Where(x => selector == value).FirstOrDefault();
}

Должен называться:

Repository.GetByProperty<SomeEntityClass>(Guid.NewGuid(), x => x.MyClassProperty );
Repository.GetByProperty<AnotherEntityClass>(Guid.NewGuid(), x => x.AnotherProperty);

но это не работает.

Любая помощь?

Спасибо.

Ответы [ 3 ]

7 голосов
/ 16 ноября 2011

Попробуйте использовать что-то подобное:

public T GetByProperty<T, TValue>(TValue value, Expression<Func<T, TValue>> selector) {
    var predicate = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(selector.Body, Expression.Constant(value)), 
        selector.Parameters
    );

    return Session.Query<T>().Where(predicate).FirstOrDefault();
}
1 голос
/ 16 ноября 2011

Аналогично ответу SWeko, альтернатива, позволяющая вам ввести idSelector (чтобы предотвратить сравнение от Object до Guid ...)

public T GetById<T, TKey>(TKey id, Func<T, TKey> idSelector)  
{  
    return Session.Query<T>().FirstOrDefault(x => idSelector(x) == id);  
}

Вы бы назвали это примерно так..

var result = GetById(guidId, (AnotherEntityClass x) => x.MyClassId);

Более того, если вы добавили следующий класс ...

public class YetAnotherEntityClass
{
    public long MyId {get;set}
}

Вы все еще можете использовать тот же метод ...

var result = GetById(12345, (YetAnotherEntityClass x) x=> x.MyId;

Если вы обнаружите, что это приводит к полной загрузке таблицы, учтите следующее:

public T GetFirstByCriterion<T, bool>(Expression<Func<T, bool>> criterion)
{
    return Session.Query<T>().FirstOrDefault(criterion);
}

, который можно вызвать с помощью

var result = GetFirstByCriterion((AnotherEntityClass x) x => x.AnotherProprty = guidId);
1 голос
/ 16 ноября 2011

Вам нужно вызвать селектор на объекте, поэтому что-то вроде этого должно работать

public T GetById<T>(Guid id, Func<T, object> idSelector)
{
    return Session.Query<T>().Where(x => idSelector(x) == id).FirstOrDefault();
}

Также вместо комбо Where / First(OrDefault), в подобных ситуациях я обычно использую Single(OrDefault) потому что мне нравится, когда возникает исключение, если где-то есть дубликат ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...