2016-12-09 23 views
0

私は最終的に明らかにそれは勝ったエラー - タイプXの変数がスコープから参照が、それは定義されていない

SELECT p.* 
FROM MyEntity p 
WHERE EXISTS(SELECT * 
      FROM filters 
      WHERE (filter.type = 1 
        AND filter.objectid = p.id 
        AND filter.value = 1 
        OR filter.type = 1 
        AND filter.objectid = p.id 
        AND filter.value = 2)) 
    AND EXISTS(...) 

のようなクエリで結果式を構築しようとしていますまったく同じように見えますが、それは一般的な考え方です。 私は渡されたフィルタに基づいてクエリを構築するためにPredicateBuilderを使用していますので、私はこのようなものがあります:

var query = context.Set<MyEntity>().AsExpandable(); 

var predicate = PredicateBuilder.New<MyEntity>(true); 

//loop through the group filters. The filters in a group have an or relationship 
foreach (FilterGroup group in filters) 
{ 
    predicate = predicate.And(
       p => context.Set<FilteringValue>().AsExpandable().Any(getFilteringPredicate(p,group)) 
    ); 
} 

return query.Where(predicate); 

そしてgetFilteringPredicateMethod:

Expression<Func<FilteringValue,bool>> getFilteringPredicate(MyEntity p, FilterGroup filters) { 

    var fPredicate = PredicateBuilder.New<FilteringValue>(true); 
    foreach(var filter in filters.FilterList) 
    { 
     fPredicate= fPredicate.Or(fv => fv.objectid == p.Id && fv.Type== 1 && fv.value == filter.Value); 
    } 

    return fPredicate 
} 

これは比較的単純なようだが、しかし、私は」エラーが発生する

変数 'p'が 'Models.MyEntity'のスコープ ''から参照されていますが、定義されていません。

getFilteringPredicate()メソッドに製品オブジェクトを渡す方法はありませんか? MyEntityとFilterはEntity Frameworkには関係ありません。

+0

ない完全な答えをしていますが、 '述語ビルダーを初期化する必要がありますfPredicate' 'Or'sを使用すると、' getFilteringPredicate'をfalseにします。 –

+0

また、「MyEntityとFilterはEntity Frameworkには関係ありません。」 - おそらく、それらはおそらくEntity Frameworkに関連していません。関連する必要があります。 –

+0

私はこれをより詳細に分析します。私の最初のテストはうまく見えました。私は答えがあると思っていましたが、そうではありません。私はそれに刻んだショットを与えて答えを投稿します –

答えて

0

だから私は最終的にそれを得たと思います。あなたは2つの式のパラメータを関連させ、複合クエリを構築したいと思います(私は "複合"の非公式な定義を意味しています)パラメータ(秒)):

残念ながら、LinqKitは、あなたのケースのための完璧な試合になると何かであるマルチパラメータ表現「私の知る限り」をサポートしていません。

まあ、とにかく...ここにそれが行きます。 FilteringValuesMyEntitiesはちょうど2つのDbSetsですちなみに、私はちょうどATM(?質問)これをテストするためにLinqPadを使用することが起こる:

void Main(string[] args) 
{ 
    var entityQuery = MyEntities.AsExpandable(); 

    var filterGroups = GetFilterGroups(); 

    // Initialize with TRUE since no group filter implies Everything matches 
    var predicate = PredicateBuilder.New<MyEntity>(true); 

    var filteringValueQuery = FilteringValues.AsExpandable(); 

    foreach (var g in filterGroups) 
    { 
     if (!g.FilterList.Any()) 
     { 
      // If we have no filters in the group, skip 
      continue; 
     } 
     var expressionForGroupFilters = BuildExpressionForGroupFilters(g.FilterList); 
     predicate = predicate.And(entity => filteringValueQuery.Any(filteringValue => expressionForGroupFilters.Invoke(entity, filteringValue))); 
    } 

    entityQuery = entityQuery.Where(predicate); 

    var data = entityQuery.ToList(); 

    data.Dump(); 
} 

public static Expression<Func<MyEntity, FilteringValue, bool>> BuildExpressionForSingleFilter(Filter groupFilter) 
{ 
    var value = groupFilter.Value; 
    return (entity, filteringValue) => 
     filteringValue.Type == 1 
     && filteringValue.ObjectId == entity.Id 
     && filteringValue.Value == value; 
} 

public static Expression<Func<MyEntity, FilteringValue, bool>> BuildExpressionForGroupFilters(IReadOnlyCollection<Filter> groupFilters) 
{ 
    Expression<Func<MyEntity, FilteringValue, bool>> result = null; 

    foreach (var groupFilter in groupFilters) 
    { 
     var expression = BuildExpressionForSingleFilter(groupFilter); 
     if (result == null) 
     { 
      result = expression; 
      continue; 
     } 

     var tempResult = result.Expand(); 
     result = (entity, filteringValue) => tempResult.Invoke(entity, filteringValue) || expression.Invoke(entity, filteringValue); 
    } 

    return result.Expand(); 
} 

public static FilterGroup CreateFilterGroupWithValues(params int[] values) 
{ 
    var filterList = values 
     .Select(x => new Filter { Value = x }) 
     .ToList(); 

    return new FilterGroup { FilterList = filterList }; 
} 

public static IEnumerable<FilterGroup> GetFilterGroups() 
{ 
    return new[] {CreateFilterGroupWithValues(0, 2, 4), CreateFilterGroupWithValues(1)}; 
} 

public class Filter 
{ 
    public int Value { get; set; } 
} 

public class FilterGroup 
{ 
    public FilterGroup() 
    { 
     FilterList = new List<Filter>(); 
    } 

    public List<Filter> FilterList { get; set; } 
} 
関連する問題