Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用“a”中的列表编写LINQ到实体查询;其中;条件_C#_Linq - Fatal编程技术网

C# 如何使用“a”中的列表编写LINQ到实体查询;其中;条件

C# 如何使用“a”中的列表编写LINQ到实体查询;其中;条件,c#,linq,C#,Linq,我想知道如何以列表为条件编写最有效的LINQ(编辑:到实体)查询。事情是这样的 假设我们有以下数据结构: public class Recipe { public int Id; public string Name; public List<Ingredient> IngredientList; } public class Ingredient { public int Id; public string Name; } 公共类配方

我想知道如何以列表为条件编写最有效的LINQ(编辑:到实体)查询。事情是这样的

假设我们有以下数据结构:

 public class Recipe
 {
   public int Id;
   public string Name;
   public List<Ingredient> IngredientList;
 }

 public class Ingredient
 {
   public int Id;
   public string Name;
 }
公共类配方
{
公共int Id;
公共字符串名称;
公共列表-信用列表;
}
公共类成分
{
公共int Id;
公共字符串名称;
}
现在,我想做一个查询,搜索所有含有给定成分的配方

 public List<Recipe> GetRecipesWhichHaveGivenIngredients(List<Ingredients> ingredients)
 {
   List<Recipe> recipes;

   using (DataContext context = new DataContext())
   {
    //efficient LINQ query goes here
    recipes = context.Recipes.Where(recipe => /*medaCode recipe.IngredientList.Contains(ingredients) */).ToList();
   }
   return recipes;
 }
public List获取含有给定成分的配方(列出成分)
{
列出食谱;
使用(DataContext=newdatacontext())
{
//这里是高效的LINQ查询
recipes=context.recipes.Where(recipe=>/*medaCode recipe.IngreditList.Contains(配料)*/).ToList();
}
返回食谱;
}
基本上,这就是如何确定一个给定集是否是另一个集的子集的问题

我尝试了以下查询(主要思想是使用Intersect操作):

List recipes=dataContext.recipes.Include(“Ingrediens”).Where(rec=>rec.IngredientList.Select(ingr=>ingr.Id).Intersect(components.Select(sy=>sy.Id)).Count()==components.Count).ToList();
但我得到了以下错误:

无法创建的常量值 类型“闭包类型”。只有原始的 类型('如Int32、String和 在此上下文中支持Guid')


好的,如果
IngredientList
确实是一个
列表
,您将能够执行以下操作:

recipes = context.Recipes.Where(recipe => recipe.IngredientList.Exists(i => i.Id == ingredient.Id)).ToList();
但这意味着所有列表都需要填充。由于这看起来像一个LINQ到SQL的查询,我猜
IngreditList
只是一个连接的表。。。?在这种情况下,您将没有完整的列表,但仍然可以执行类似的操作:

recipes = context.Recipes.Where(recipe => recipe.IngredientList.Count(i => i.Id == ingredient.Id) > 0).ToList();
…它仍然应该只查询sql server一次

编辑

正如刚才在评论中指出的,这并不能完全回答这个问题。至于包含所有搜索,我不认为不循环输入就可以完成。好的方面是,这可以在不枚举IEnumerable
配方的情况下完成,因此下面的代码仍然只会在sql server上运行一次,只需执行一次查询:

var recipes = context.Recipes.AsEnumerable<Recipe>();

ingredients.ForEach(i =>
    var recipes = recipes.Where(r =>
        r.IngredientList.Count(ii => ii.Id == i.Id) > 0
    );
);

return recipes.ToList();
var recipes=context.recipes.AsEnumerable();
成分。ForEach(i=>
var recipes=配方。其中(r=>
r、 IngCreditList.Count(ii=>ii.Id==i.Id)>0
);
);
return recipes.ToList();

在点击
ToList()
之前,不会执行查询。

不知道这在Linq2SQL中是否有效,但在Linq2Object中,这是有效的:

public static class Util
{
    public static List<Recipe> GetRecipesWhichHaveGivenIngredients(this List<Recipe> recipies, List<Ingredient> ingredients)
    {
        int icount=ingredients.Count;

        var res = recipies.Where(r => r.IngredientList.Where(i => ingredients.Contains(i)).Count() == icount).ToList();
        return res;
    }
}
公共静态类Util
{
公共静态列表获取包含给定成分的配方(此列表为配方,列出成分)
{
int icount=配料数;
var res=recipies.Where(r=>r.IngredientList.Where(i=>components.Contains(i)).Count()==icount.ToList();
返回res;
}
}
不要使用
列表
查找您想要查找的成分;使用
HashSet
ispropertsubsetof
方法,该方法接受集合作为其参数:

.Where(x => ingredients.IsProperSubsetOf(x.IngredientList))
除了作为一个O(n+m)操作之外,它还有一个额外的好处,就是当您看到它时,它可以告诉您它在做什么

编辑

如果上述情况不清楚:

public List<Recipe> GetRecipesWhichHaveGivenIngredients(HashSet<Ingredient> ingredients)
{
   using (DataContext context = new DataContext())
   {
       return context.Recipes
           .Where(x => ingredients.IsProperSubsetOf(x.IngredientList)  
           .ToList();
   }
 }
public List获取包含给定成分的配方(HashSet成分)
{
使用(DataContext=newdatacontext())
{
返回上下文
.Where(x=>components.ispropertsubsetof(x.IngredientList)
.ToList();
}
}

从何处获取配料对象(配料.Id)?此方法获取Ingredines(即IEnumerable)。你不使用它。嘿,对不起。然后我完全错过了问题的要点:o我把它看作是内部列表问题中的一个查找事件。我将根据Lyok进行编辑,但我如何在LINQ to Entities中使用它?@peter:EF3.5无法为ISPropertSubsetof创建SQL。NotSupportedException:LINQ to Entities不识别方法“Boo”精益ispropertsubsetof(System.Collections.Generic.IEnumerable`1[System.String])方法,并且该方法无法转换为存储表达式。最后,我使用David的方法,在内存中进行过滤。我知道EF SQL在运行中支持—所以一定有办法通过LINQ到EF实现这一点?
public List<Recipe> GetRecipesWhichHaveGivenIngredients(HashSet<Ingredient> ingredients)
{
   using (DataContext context = new DataContext())
   {
       return context.Recipes
           .Where(x => ingredients.IsProperSubsetOf(x.IngredientList)  
           .ToList();
   }
 }