簡體   English   中英

檢查一個集合是否包含來自具有延遲執行的另一個集合的所有值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM