改进MongoDB LINQ表达式以避免每个循环

时间:2014-06-20 16:44:59

标签: c# linq mongodb mongodb-.net-driver

我通过C#驱动程序查询mongodb集合,但是无法提出可以根据SubCategory每个类别的限制删除Items的LINQ表达式。在下面的测试中,如果Item在类别22中且Item也在SubCategory A或B中,则不应从查询中返回Item。

测试通过了当前编写的内容,但我觉得有一种更好的方法可以在不使用foreach循环的情况下执行此操作。有什么想法吗?

[Test]
public void RemoveItemsBasedOnCategorySubCategoryRestrictions()
{
    var restrictionsByCategorySubCategories = new Dictionary<String, List<String>> {
        { "22", new List<String> { "A", "B" } },
        { "32", new List<String> { "A" } }
    };

    var items = new List<Item> { 
        new Item { Category = "32", SubCategory = new List<String> { "Z" } },
        new Item { Category = "32", SubCategory = new List<String> { "A" } }, 
        new Item { Category = "22", SubCategory = new List<String> { "Z" } },
        new Item { Category = "22", SubCategory = new List<String> { "A" } },
        new Item { Category = "22", SubCategory = new List<String> { "B" } } 
    }.AsQueryable();

    var results = new List<Item>();

    foreach (var restrictionsByCategorySubCategory in restrictionsByCategorySubCategories)
    {
        var category = restrictionsByCategorySubCategory.Key;
        var subCategories = restrictionsByCategorySubCategory.Value;

        results.AddRange(items.Where(p => p.Category.Equals(category) && !p.SubCategory.ContainsAny(subCategories)));
    }

    Assert.That(results.ToList(), Has.Count.EqualTo(2));

    foreach (var result in results)
    {
        Assert.That(result.SubCategory, Is.Not.EqualTo("A"));
        Assert.That(result.SubCategory, Is.Not.EqualTo("B"));
    }
}

档案:

class Item
{
    public String Category;
    public List<String> SubCategory;
}

1 个答案:

答案 0 :(得分:0)

我会使用restrictions字典名称代替restrictionsByCategorySubCategories来使代码更紧凑:

var results =  items.Where(i =>
     !restrictions.ContainsKey(i.Category) ||
     !restrictions[i.Category].Intersect(i.SubCategory).Any());

或查询语法:

var results = 
   from i in items
   where !restrictions.ContainsKey(i.Category) ||              
         !restrictions[i.Category].Intersect(i.SubCategory).Any()
   select i;

逻辑非常简单 - 您获得的项目在限制列表中没有类别,或者在受限类别子类别中没有任何子类别。

结果:

[
  { Category: "32", SubCategory: [ "Z" ] },
  { Category: "22", SubCategory: [ "Z" ] }
]

不知道Linq到MongoDb是否可以翻译这个查询,但你的代码没有任何Linq到MongoDb - 它只是Linq to Objects。