2012-10-09 100 views
0

我有下面的linq语句。我怎样才能解决这个没有循环。它是一个标签系统,我只想要一点点根据您的查询,但这样的事情是对以“myints”优化LINQ语句

int[] myints = {1,2}; 
    foreach (int tagid_temp in myints) 
    { 
    ExerciseByTagId = 
     (from exercise in context.ExerciseSet 
     where context.ItemsTagsSet 
       .Where(a => a.TagsId == tagid_temp) 
       .Select(a => a.ExerciseId).Contains(exercise.Id) 
     select exercise); 
    } 
+0

看起来你只是在循环的每个迭代中覆盖'ExerciseByTagId'。所以它将始终分配循环的最后一次迭代的值。 – Magnus

回答

0

猜测与IDS标签练习?

EDIT - 实现了我的第一个例子将返回重复练习如果发现多个匹配代码)

INT [] myints = {1,2};

ExerciseByTagId = 
    context.ExerciseSet 
      .Where(e => context.ItemsTags 
           .Any(t=> t.ExerciseId == e.Id 
             && myints.Contains(t.TagsId) 
       ); 

要获得所有相关项目都在列表中的项目:

int[] myints = new int[] {1,2}; 

var ExerciseByTagId = 
    context.ExerciseSet 
    .Where(
     e => context.ItemsTags 
        .Where(t=> t.ExerciseId == e.Id) 
        .All(t => myints.Contains(t.TagsId)) 
     ); 
+0

也许我有点不好解释,但我只想要所有标签都匹配“myint”的练习。 for循环给了我这个但不好的方式? – ahrberg

0

Contains()是非常接近你所需要的,所以用自己的ContainsAll()功能:

public static bool ContainsAll<T>(this IEnumerable<T> sequence, params T[] matches) 
{ 
    return matches.All(value => sequence.Contains(value)); 
} 
+1

这会将筛选器推送到客户端而不是数据库中,因为您使用IEnumerable而不是IQueryable。 –

+0

但是没有与“ContainsAll”函数等价的SQL。 –

0

我在短短的时间内测试了这个呃类似的数据库结构,它会产生一个单一的SQL语句:

var selected = new [] {1,2}; 

var ex = from ts in context.ItemsTagsSet 
     where selected.Contains(ts.TagsId) 
     group ts by ts.ExerciseId into g select new 
     { 
      ExerciseId = g.Key, 
      Count  = g.Count() 
     } into x 
     where x.Count == selected.Length 
     join e in context.ExerciseSet on e.ExerciseId equals x.ExerciseId 
     select e;