1

動的ジェネリック メソッドを構築しようとしていました。高度な検索メカニズムを作成するため。

Dynamic LINQ を使用して何かを達成できた

IQueryable<Table> query = ObjectContext.Table;
if (parameters != null && parameters.Count > 0)
{
    foreach (KeyValuePair<string, dynamic> keyValuePair in parameters)
    {
        query = query.Where(keyValuePair.Key + " == @0", new object[] { keyValuePair.Value });
    }
}

しかし、これを行うには、各フィールドに次のようなものをロードする必要があります

ClassTable.Parameters.Add("FKTable.Foo", foo);
ClassTable.Parameters.Add("Bar", bar);

だから私は他のアプローチを試しています(このコードは機能します)

List<Table> lstTable = new List<Table>();
lstTable.AddRange(tableDAO.SelectWhere(
    u => this.EntityValues.Foo == u.Foo && this.EntityValues.Bar == u.Bar
));
return lstTable;

さて、私の問題は、もっと似たようなことをしたかったことです(このコードは最初のクエリの結果のみをもたらします)

List<Table> lstTable = new List<Table>();
lstTable.AddRange(tableDAO.SelectWhere(
    u => !string.IsNullOrEmpty(this.EntityValues.Foo) ? this.EntityValues.Foo == u.Foo : false 
    &&
    this.EntityValues.Bar != 0 ? this.EntityValues.Bar == u.Bar : false
));
return lstTable;

こんなことしたくなかった

IQueryable<Data.Story> query = ctx.DataContext.Stories;

if (criteria.StoryId != null) // StoryId
    query = query.Where(row => row.StoryId == criteria.StoryId);

if (criteria.CustomerId != null) // CustomerId
    query = query.Where(row => row.Project.CustomerId == criteria.CustomerId);

if (criteria.SortBy != null) // SortBy
    query = query.OrderBy(criteria.SortBy + " " + criteria.SortOrder.Value.ToStringForSql());

私の質問がちょっとごちゃごちゃしていることはわかっています。修正するために編集とコメントを提供します。私に知らせて。


TL;DR; 検索で使用されるパラメーターのみを渡す必要がある動的クエリを作成するには、助けが必要です。そのため、ユーザー向けの高度な検索オプションを作成できます。

4

2 に答える 2

0

pswgが彼の答えで提案したように、私は自分でやらなければなりませんでしたが、彼が提案したこととは少し異なりました。

DAO クラスに 2 つのメソッドを作成します。1 つ目は式のリストをロードし、2 つ目はそれを読み取って実行します。

public List<System.Linq.Expressions.Expression<Func<E, bool>>> whereList = new List<Expression<Func<E, bool>>>();
public List<E> ExecuteSelectFilter()
{
    System.Linq.Expressions.Expression<Func<E, bool>> whereFinal = c => true;

    foreach (System.Linq.Expressions.Expression<Func<E, bool>> whereItem in whereList)
    {
        if (whereItem != null)
        {
            var invokedExpr = Expression.Invoke(whereFinal, whereItem.Parameters.Cast<Expression>());

            whereFinal = Expression.Lambda<Func<E, bool>>
                    (Expression.AndAlso(whereItem.Body, invokedExpr), whereItem.Parameters);
        }
    }
    return this.ObjectContext.CreateQuery<E>(EntitySetName).Where(whereFinal.Compile()).ToList();
}

これらのメソッドは DAO で呼び出すので、所有しているどのビジネス クラスからでもアクセスできます。

tableDAO.whereList.Clear();

#region Filters
// Foo
if (!String.IsNullOrEmpty(this.entityValues.Foo)) 
    tableDAO.whereList.Add(q => q.Foo.Contains(this.entityValues.Foo));
// Bar
if (this.entityValues.Bar > 0) 
    tableDAO.whereList.Add(q => q.Bar== this.entityValues.Bar);
#endregion

return tableDAO.ExecuteSelectFilter();

それが私を助けたように、これが誰かを助けることを願っています。

于 2013-04-01T22:01:51.970 に答える