2

重複の可能性:
LINQ式を1つに組み合わせるにはどうすればよいですか?

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演算子と組み合わせる方法はありますか?

4

4 に答える 4

5

最も簡単な方法は、params配列をループして、式ごとに.Whereを呼び出すことです。

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

これはあなたが尋ねたものではないことを私は知っていますが、それは全体的な目標を達成するので十分かもしれませんか?

于 2012-05-07T17:16:16.360 に答える
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);

実際、私がそれを見た今、あなたはそれを1つの表現に要約することができるかもしれません:

var isUnique = (_session.QueryOver<Employee>()
   .CombinedWhere( 
        x => x.FirstName == commandMessage.FirstName, 
        x => x.LastName == commandMessage.LastName)
   .ToRowCountQuery()
   .RowCount()) == 0; // == 1?
于 2012-05-07T19:43:45.300 に答える
0

はい、.Invoke()でLinqKit使用できます

Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000;
Expression<Func<Purchase,bool>> criteria2 = p => criteria1.Invoke (p)
                                                 || p.Description.Contains ("a");
于 2012-05-07T16:41:21.560 に答える
0

BradRemとKennethItoのおかげで、彼らは私にいくつかのインスピレーションを与えてくれました。

NHibernateのIQueryOverAPIで機能するソリューションは次のとおりです。

リポジトリ:

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));
    }
}
于 2012-05-08T08:53:06.773 に答える