0

私はEFが初めてです。プロジェクトのリストを含むテーブルがあります。ソフトウェアで、すべてのプロジェクトを検索するクエリを見つけました。

public Project[] FindAll()
{
    var projects = new List<Project>();
    using (var db = new ProjetDbConext())
    {
        var qProjects = from project in db.ProjectSet
            where project.CreateDateTime != null
            select project;
        projects = qProjects.ToList();
    }
    return projects.ToArray();
}

これは問題ないようですが、パラメータ化する方法がわかりません。EF のクエリ ロジックを再利用しようとする検索機能を実装しているため、これが必要です。

これはタプルの List を取ります。各タプルには、基本的に属性と検索語のリストがあります。

例えば。Tuple(FirstName , { Prasaanth ,Bill } ; Tuple( LastName , { Neelakandan , Gates } ;

これは、FirstName が Prasaanth または Bill であるプロジェクトを検索する選択クエリを作成する必要があることを意味します。リストに用語が 1 つしかない場合。

例えば。Tuple( Company , { Microsoft} ; 次に、クエリで where 条件を 1 つだけ検索する必要があります。

 public Project[] LoadSearchProjects(List<System.Tuple<string, List<string>>> searchTerms)
        {
            var projects = new List<Project>();

            using (var db = new ProjetDbConext())
            {
                foreach (System.Tuple<string, List<string>> pair in searchTerms)
                {

                    string attribute = pair.Item1;
                    List<string> terms = pair.Item2;

                      /// logic here
                 }  
            }
            return projects.ToArray();

        }

私はいつでもif条件を書くことができます:

if(attribute.equals("FirstName"){

 // query project.FirstName in the where conditon 


}

しかし、検索するには属性が多すぎます。

私はこれを行うADO.NETの方法を知っています:

 mycommands = new SqlCommand(" select projects from from Persons where '"+attibute+"' =  some search terms ... 

EF クエリでこのようなことを行う方法がわかりません。

1) EF で動的属性の検索を行う方法はありますか? または '"+attribute+"' を使用してパラメーター化しますか??

2) を使用する代わりに、構造を単純化するために使用できるより良いデータ構造はありList<Tuple<string, List<string>>ますか?

3) サードパーティの LINQKit または動的 linq を使用することをお勧めしましたが、それを EF クエリに統合する方法がわかりません。

これの多くが大学生のコードのように聞こえる場合は、申し訳ありません。追加の詳細が必要な場合はお知らせください。

よろしく、 プラサント

更新: Andriy's answer による作業方法。ここでの私の質問は、データベース内の特定のエントリで Name is Null と表示されている場合、これは機能しないということです。

 private static Expression<Func<TEntity, bool>> BuildStringFilter<TEntity, TProp>(
            Tuple<string, List<string>> filter)
        {
          // entity is the Project table
            var entity = Expression.Parameter(typeof (TEntity));
            var prop = Expression.Property(entity, filter.Item1);

            //check if contains returns true

            var body = filter.Item2
                .Select(v => Expression.Equal(Expression.Call(prop,
                    typeof (String).GetMethod("Contains"),
                    new Expression[] { Expression.Constant(v) }), Expression.Constant(true)))
                .Aggregate(Expression.Or);



            var result = (Expression<Func<TEntity, bool>>) Expression.Lambda(body, entity);
            return result;
        }

式を変更して、Contains メソッドを次のように変更できます。

prop, typeof (String).GetMethod("Contains"), new Expression[] { Expression.Constant(v)

属性 (prop) の値が null の場合に機能しますか?

4

2 に答える 2

2

スニペットを使用してフィルター式を作成できます。

public static Expression<Func<TEntity, bool>> BuildFilter<TEntity, TProp>(
    KeyValuePair<string, IEnumerable<TProp>> filter)
{
    var entity = Expression.Parameter(typeof(TEntity));
    var prop = Expression.Property(entity, filter.Key);

    var body = filter.Value
        .Select(v => Expression.Equal(prop, Expression.Constant(v)))
        .Aggregate((curr, next) => Expression.Or(curr, next));

    var result = (Expression<Func<TEntity, bool>>)Expression.Lambda(body, entity);
    return result;
}

そして、次のように呼び出します。

var filter = new KeyValuePair<string, IEnumerable<string>> (
    "FirstName",
    new [] {"Alice", "Bob"}
);

var predicate = BuildFilter<Item, string>(filter);
var result = ctx.Items.Where(predicate);

また、「方法: 式ツリーを使用して動的クエリを作成する」も参照してください。

于 2015-07-17T19:00:04.630 に答える