0

私はいくつかのデータを返すための次のメソッドを持っています:

public List<Document> GetDocumentsList(Guid sessionID, bool includeValid, bool includeExpired, bool includeAboutToExpire)
{
   using (DB db = new DB())
   {
       // get the active documents
       var docs = db.Documents
                  .Where(d =>
                      db.EmployeeStatuses
                     .Any(s => s.EmpID == d.EmpID && s.StatusEndDate == null && s.Status == "Active")
                        );

        // how to filter the result depending on includeValid, includeExpired and includeAboutToExpired parameters?

        return docs.ToList()
    }
}

ここでの問題は、パラメーターに応じて結果をフィルター処理したいということです。boolたとえば、includeValidが true の場合は有効なドキュメントが含まれ、includeExpiredが true の場合は期限切れのドキュメントが含まれます。3 つすべてを取得できます。 true またはそれらの 1 つまたは 2 つが true です。DB を複数回呼び出したくありません。1回の呼び出しでこれを行うことができるロジックはありますか?

4

4 に答える 4

5

LinQ to entities は、結果が列挙されるまで実行を延期します。したがって、後続の.Where()ステートメントを追加しても、データベースへの複数の呼び出しが発生することはありません

var docs = db.Documents
                  .Where(d =>
                      db.EmployeeStatuses
                     .Any(s => s.EmpID == d.EmpID && s.StatusEndDate == null && s.Status == "Active")
                        );

if (includeValid)
   docs = docs.Where(x => [condition]);

//... and so on.

return docs.ToList(); // <- This is where the query is actually executed. 
于 2013-02-04T16:07:26.377 に答える
1

実装を使用できますPredicateBuilder。このクラスを使用すると、linq クエリにいくつかのフィルターを適用できます。このようなもの:

public IEnumerable<Document> GetDocumentsList(Guid? sessionID, bool? includeValid, bool? includeExpired, bool?  includeAboutToExpire)
{
    var query = db.Documents;

    if (sessionID.HasValue)
       query = query.And(x => x.SessionID = sessionID.Value);

    if (includeValid.HasValue && includeValid.Value)
       query = query.And(x => x.IncludeValid = includeValid.Value);

    // others parameters...

    return query.ToList();
}

PredicateBuilder の実装

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

public static class PredicateBuilder
{
  public static Expression<Func<T, bool>> True<T> ()  { return f => true;  }
  public static Expression<Func<T, bool>> False<T> () { return f => false; }

  public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                      Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
  }

  public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                       Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
  }
}
于 2013-02-04T16:14:37.947 に答える
0

このようなものはどうですか?(もちろん、これらのフラグがどのように評価されることになっているのかを仮定しています)。

public List<Document> GetDocumentsList(Guid sessionID, bool includeValid, bool includeExpired, bool includeAboutToExpire)
{
   using (DB db = new DB())
   {
       // get the active documents
       var docs = db.Documents
                  .Where(d =>
                      db.EmployeeStatuses
                     .Any(s => s.EmpID == d.EmpID 
                               && s.StatusEndDate == null 
                               && (s.Status == "Active"
                                 || (includeValid && s.Status == "Valid")
                                 || (includeExpired && s.Status == "Expired")
                                 || (includeAboutToExpired && s.Status == "AboutToExpired") ))
                        );

        // how to filter the result depending on includeValid, includeExpired and includeAboutToExpired parameters?

        return docs.ToList()
    }
}
于 2013-02-05T11:55:45.743 に答える
0

ドキュメントとステータスの結合が必要なようです。また、条件(!includeValid || d.Valid)により、有効なドキュメントのみをフィルタリングできます。IDincludeValidtrue次のとおりです。

public List<Document> GetDocumentsList(Guid sessionID, 
       bool includeValid, bool includeExpired, bool includeAboutToExpire)
{
   using (DB db = new DB())
   {
       // get the active documents
       var docs = from d in db.Documents
                  join s in db.EmployeeStatuses on d.EmpID equals s.EmpID
                  where s.StatusEndDate == null &&
                        s.Status == "Active" &&
                        (!includeValid || d.Valid) &&
                        (!includeExpired || d.Expired) &&
                        (!includeAboutToExpired || d.AboutToExpired)
                  select d;

        return docs.ToList()
    }
}
于 2013-02-04T16:16:39.963 に答える