[英]Check if a collection contains ALL values from another collection with Deferred Execution
考虑以下类别:
public class Recipe
{
public string Id { get; set; }
public ICollection<RecipeFacet> RecipeFacets { get; set; }
}
public class RecipeFacet
{
public string Id { get; set; }
public Facet Facet { get; set; }
public string RecipeId { get; set; }
}
public class Facet
{
public string Name { get; set; }
}
我需要改善现有查询。 我当时在考虑使用Linq的延迟执行。 我将如何编写仅返回包含我在Tuples
列表中指定的所有Facets
Recipes
的Linq查询?
这是循环遍历Recipes
及其Facets
的原始代码。 它可以工作,但是如果我的初始results
查询中包含很多Recipes
,则速度会很慢。
IQueryable<Recipe> result; //assume we have data here
string query = "Cuisine:American+Recipe-Type:dinners";
IEnumerable<Tuple<string, string>> taxFacets = query
.Split(' ')
.Select(tf => tf.Split(':'))
.Select(tf => new Tuple<string, string>(tf[0], tf[1]))
.Distinct();
var recipeFacetCollection = result.Select(r => r.RecipeFacets).ToList();
var matchedRecipesIds = new List<string>();
var recIds = result.Select(r => r.Id).ToList();
// initially, include all recipes
matchedRecipesIds.AddRange(recIds);
// loop through each recipe's facet collection
foreach (var col in recipeFacetCollection)
{
// loop through the tax facets from the query
foreach (var tf in taxFacets)
{
var exists = col.Any(f => f.Facet.Name.Equals(tf.Item2, StringComparison.OrdinalIgnoreCase));
// remove any recipe that is missing a facet
if (!exists)
{
matchedRecipesIds.Remove(col.First().RecipeId);
}
}
}
result = result.Where(r => matchedRecipesIds.Contains(r.Id));
我怎样才能有一个不错的延期执行的Linq查询?
更新::
把我的元组变成一个列表可以使我做到这一点。 但是此查询不会返回我的任何记录。
这是我的标准:
Recipes
,有集合RecipeFacts
,包含Facets
有名称=“美国” AND NAME =“晚餐”。
var listFacets = new List<string>()
{
"American",
"dinners"
};
result = result
.Where(r => r.RecipeFacets
.All(f => !listFacets.Any(t => t.Equals(f.Facet.Name, StringComparison.OrdinalIgnoreCase))));
您的查询逻辑选择listFacets中不存在其面的所有配方。 @Hung的逻辑更接近,但选择的所有方面都在listFacets中的食谱
我认为您想选择包含所有listFacets的所有配方。
简化示例以使用字符串列表:
var listFacets = new[] { "a", "d" };
var recipes = new[] { new[] { "a" },
new[] { "a", "d" },
new[] { "a", "d", "e" },
new[] { "x" }
};
// correct query, returns 2 results ad and ade
var result = recipes.Where(r => listFacets.All(f => r.Any(rf => rf == f)));
// original incorrect query, returns x
var result2 = recipes.Where(r => r.All(f => !listFacets.Any(rf => rf == f)));
我不太确定,因为您的代码块很长,但这是我能想到的
result = result.Where(r => r.RecipeFacets.All(f => taxFacets.Any(t => t.Item1.Equals(f.Facet.Name))));
让我知道是否有帮助
从listFacets集合的检查中的子句中删除惊叹号。
result = result.Where(r => r.RecipeFacets.All(f => listFacets.Any(t => t.Equals(f.Facet.Name, StringComparison
我是从@Rimp的帮助中获得的。
在哪里 -过滤器
ALL-要求listFacets
中的所有值
ANY-位于任何Facets
。
result = result
.Where(x => listFacets
.All(lf => x.RecipeFacets
.Any(f => f.Facet.Slug.Equals(lf, StringComparison.OrdinalIgnoreCase))));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.