在linq中使用ALL运算符过滤EntitySet的子项 [英] Using the ALL operator in linq to filter child items of EntitySet

查看:41
本文介绍了在linq中使用ALL运算符过滤EntitySet的子项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个对象,如下所示:

I have a two objects as follows:

public class Item
{
    public int ItemId {get;set;}
    public string ItemName {get;set;}
    public List<Tag> ItemTags {get;set;}
    public DateTime DateCreated {get;set;}
}

public class Tag
{
    public int TagId {get;set;}
    public string TagName {get;set;}
}

这些是LINQ-to-SQL对象,因此ItemTag将是一个EntitySet.

These are LINQ-to-SQL objects, so the ItemTags will be an EntitySet.

我正在尝试执行搜索查询,用户可以在其中提供以逗号分隔的标签列表作为搜索过滤器.

I am trying to perform a search query where a user can provide a comma delimited list of tags as a search filter.

如何将项目列表过滤为包含逗号分隔列表中所有标记的项目.

How do I filter my list of items to those which contains all of the tags in the comma delimited list.

EDIT2

e.g.
Item1 has tags of Apple, Banana, Orange
Item2 has tags of Banana, Orange
Item3 has tags of Pineapple, Orange
If the tag filter is "Banana, Orange" I need the results to be Item1 and Item2.

/EDIT2

这是我到目前为止尝试过的:

This is what I have tried thus far:

string tags = "Manchester United,European Cup,2008";
List<string> tagsList = tags.Trim().ToLower()
    .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
    .Distinct(StringComparer.CurrentCultureIgnoreCase)
    .ToList();

List<Item> itemList = ItemRepository.FetchAll();

var query = itemList
    .OrderByDescending(p => p.DateCreated)
    .ToList();

if (tagsList.Count() > 0)
{
    query = query
        .Where(p => p.ItemTags
            .Select(q => q.TagName.ToLower())
            .All(r => tagsList.Contains(r)))
        .ToList();
}

但是,这似乎不起作用.对我在做什么错有任何想法吗?

However, this doesn't seem to work. Any ideas on what I am doing wrong please?

标记被修剪并被小写".

tags are trimmed and are 'lowercased'.

推荐答案

那是因为您要将项目中的标签放到小写字母,而不是搜索到的标签.

That because you're puting the tags from the items to lowercase, but not the searched tags.

通过此修改,它应该可以工作:

With this modification it should work:

List<string> tagsList = tags
    .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
    .Select(s => s.ToLower())
    .Distinct()
    .ToList();


好的,我明白了问题所在:您正在反向进行此操作.您正在搜索仅具有 您要查找的标签的商品.


OK, I see what the problem is: you're doing it backwards. You're searching for items that have only the tags that you're looking for.

尝试尝试:

query = 
    (from item in query
     let itemTags = p.ItemTags.Select(it => it.TagName.ToLower())
     where tags.All(t => itemTags.Contains(t))
     select item).ToList();


更新:这是带有lambda语法的版本.由于临时的匿名类型,这很丑陋,但这是let子句转换为lambda的方式...


UPDATE: here's a version with the lambda syntax. It's pretty ugly because of the temporary anonymous type, but that's how the let clause translates to lambda...

query =
    query.Select(item => new { item, itemTags = item.ItemTags.Select(it => it.TagName.ToLower()) })
         .Where(x => tagsList.All(t => x.itemTags.Contains(t)))
         .Select(x => x.item)
         .ToList();

这篇关于在linq中使用ALL运算符过滤EntitySet的子项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆