属性选择器和使用Linq的<t>查询</t>

时间:2011-11-16 10:34:57

标签: c# linq lambda

我正在尝试这样做:

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 个答案:

答案 0 :(得分:7)

尝试使用类似的东西:

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 :(得分:1)

你需要在对象上调用选择器,所以这样的东西应该起作用

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)因为我喜欢在某处有重复键时抛出异常。

答案 2 :(得分:1)

与SWeko的答案类似,允许您输入idSelector的替代方法(以防止ObjectGuid的比较......)

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