2012-05-07 27 views
2

可能重複:
How do I combine LINQ expressions into one?結合的表情Where語句

public bool IsUnique(params Expression<Func<Employee, bool>>[] properties) 
{ 
    var combinedProperties = Combine(properties); 
    var rowCount = _session.QueryOver<Employee>().Where(combinedProperties).ToRowCountQuery().RowCount(); 
    return rowCount == 0; 
} 

Expression<Func<Employee, bool>> Combine(Expression<Func<Employee, bool>>[] properties) 
{ 
    ??? 
} 

用法:

var isUnique = _employeeRepository.IsUnique(x => x.FirstName == commandMessage.FirstName, x => x.LastName == commandMessage.LastName); 

有謂詞與AND運算符相結合的方法?

回答

5

最簡單的方法是循環在你的參數數組和調用。凡每個表達式。

Pseudo 
var query = _session.QueryOver<Employee>() 
for each expression in expressions 
    query = query.Where(expression) 

我知道這不完全是你問的,但它可能是足夠好的,因爲它實現了總體目標?

0

是的,你可以使用LinqKit與.Invoke()

Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000; 
Expression<Func<Purchase,bool>> criteria2 = p => criteria1.Invoke (p) 
               || p.Description.Contains ("a"); 
1

我想擴展方法會更有用,將與所有的IEnumerable查詢工作:

public static class MyExtensions 
{ 
    // usage: 
    // myList.CombinedWhere(x => x.Name == "John", x => x.City == "Miami", x => x.Code > 5); 
    public static IEnumerable<T> CombinedWhere<T>(this IEnumerable<T> source, 
     params Func<T, bool>[] predicates) 
    { 
     var query = source.Where(l => true); 
     foreach(var pred in predicates) 
     { 
      query = query.Where (pred); 
     } 
     return query; 
    } 
} 

使用這個就像你使用Where擴展,除了可以使用可變數量的參數。其實

public bool IsUnique(params Func<Employee, bool>[] predicates) 
{ 
    var rowCount = _session.QueryOver<Employee>() 
      .CombinedWhere(predicates).ToRowCountQuery().RowCount(); 
    return rowCount == 0; 
} 

var isUnique = _employeeRepository.IsUnique(
      x => x.FirstName == commandMessage.FirstName, 
      x => x.LastName == commandMessage.LastName); 

,現在我看的話,你可能只是能夠熬下來到一個表達:

隨着加入上述擴展的,你的代碼稍有變化

var isUnique = (_session.QueryOver<Employee>() 
    .CombinedWhere( 
     x => x.FirstName == commandMessage.FirstName, 
     x => x.LastName == commandMessage.LastName) 
    .ToRowCountQuery() 
    .RowCount()) == 0; // == 1? 
0

感謝Brad Rem和Kenneth Ito他們給了我一些靈感。

以下是適用於NHibernate的IQueryOver API的解決方案。

庫:

public bool IsUnique(int id, params Expression<Func<T, bool>>[] properties) 
{ 
    var rowCount = _session.QueryOver<T>().CombinedWhere(properties).ToRowCountQuery().RowCount(); 
    // create 
    if (id == 0) 
    { 
     return rowCount == 0; 
    } 
    // update 
    return rowCount <= 1; 
} 

IQueryOver擴展:

public static class IQueryOverExtension 
{ 
    public static IQueryOver<T, T> CombinedWhere<T>(this IQueryOver<T, T> source, params Expression<Func<T, bool>>[] predicates) 
    { 
     return predicates.Aggregate(source, (current, predicate) => current.Where(predicate)); 
    } 
}