使用 LINQ 返回属于列表中所有标签的产品

发布于 2024-12-31 21:37:31 字数 2139 浏览 3 评论 0原文

我有一个服务方法,它接受分隔的标签列表,并应该返回分配给该列表中所有标签的产品列表。

这就是我所拥有的,它不返回任何产品。我仔细检查了数据,有一个产品属于两个标签。

public List<Product> GetTagProducts(string tags)
{
    //list of parameters
    var tagParams = tags.Split('+').ToList();

    //return all products which belong to ALL tags specified in tagParams list
    return (from pt in _repository.ProductTags
            where tagParams.All(p => p == pt.Tag.Name)
            select pt.Product).Distinct().Take(75).ToList();
}

public class Tag
{
    [Key]
    public int TagId { get; set; }
    public string Name { get; set; }

    public virtual List<Product> Products { get; set; }
    public virtual List<ProductTag> ProductTags { get; set; }

}

public class Product
{
    public int ProductId { get; set; }
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }
    [Required]
    [Display(Name = "Short Description")]
    public string ShortDescription { get; set; }
    [Required]
    [Display(Name = "Long Description")]
    public string LongDescription { get; set; }
    [Required]
    [Display(Name = "Price")]
    public decimal Price { get; set; }

    public virtual List<Tag> Tags { get; set; }
}

public class ProductTag
{
    [Key]
    public int ProductTagId { get; set; }
    [ForeignKey("Product")]
    public int ProductId { get; set; }
    [ForeignKey("Tag")]
    public int TagId { get; set; }

    public virtual Product Product { get; set; }
    public virtual Tag Tag { get; set; }
}

//Repository
private DatabaseContext _context = new DatabaseContext();
public IQueryable<ProductTag> ProductTags
    {
        get { return _context.ProductTags; }
    }



编辑:澄清我正在寻找的结果。假设 tagParams 包含两个标签字符串(意味着我正在搜索标记有这两个标签的产品):

Automotive
General

假设我们有以下产品:

product             tags
-------             ----
Wipers              Automotive, General
Air Freshener       General
Gloves              General
Tires               Automotive
Mirror              Automotive, General

查询应返回“Wipers”和“Mirror”。

I have a service method which accepts a delimited list of tags and is supposed to return a list of products which are assigned to all tags in that list.

This is what I have, and it returns no products. I've double-checked the data, there IS a product that belongs to two tags.

public List<Product> GetTagProducts(string tags)
{
    //list of parameters
    var tagParams = tags.Split('+').ToList();

    //return all products which belong to ALL tags specified in tagParams list
    return (from pt in _repository.ProductTags
            where tagParams.All(p => p == pt.Tag.Name)
            select pt.Product).Distinct().Take(75).ToList();
}

public class Tag
{
    [Key]
    public int TagId { get; set; }
    public string Name { get; set; }

    public virtual List<Product> Products { get; set; }
    public virtual List<ProductTag> ProductTags { get; set; }

}

public class Product
{
    public int ProductId { get; set; }
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }
    [Required]
    [Display(Name = "Short Description")]
    public string ShortDescription { get; set; }
    [Required]
    [Display(Name = "Long Description")]
    public string LongDescription { get; set; }
    [Required]
    [Display(Name = "Price")]
    public decimal Price { get; set; }

    public virtual List<Tag> Tags { get; set; }
}

public class ProductTag
{
    [Key]
    public int ProductTagId { get; set; }
    [ForeignKey("Product")]
    public int ProductId { get; set; }
    [ForeignKey("Tag")]
    public int TagId { get; set; }

    public virtual Product Product { get; set; }
    public virtual Tag Tag { get; set; }
}

//Repository
private DatabaseContext _context = new DatabaseContext();
public IQueryable<ProductTag> ProductTags
    {
        get { return _context.ProductTags; }
    }

EDIT: to clarify the result I'm looking for. Lets say tagParams holds two tag strings (meaning I am searching for products tagged with BOTH of these):

Automotive
General

And lets say we have the following products:

product             tags
-------             ----
Wipers              Automotive, General
Air Freshener       General
Gloves              General
Tires               Automotive
Mirror              Automotive, General

The query should return "Wipers" and "Mirror".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷路的信 2025-01-07 21:37:31

方法链样式:

List<Product> allProducts = GetAllProductsFromSomewhere();
allProducts.Where(p => tagParams.All(tag => 
p.Tags.Select(x => x.Name).Contains(tag))).Distinct().Take(75).ToList();

All 表示所有标签应等于一个标签。而且你说它包含两个标签,所以这是不可能的。
MSDN 的话来说:

确定序列中的所有元素是否满足条件。

Method chain style:

List<Product> allProducts = GetAllProductsFromSomewhere();
allProducts.Where(p => tagParams.All(tag => 
p.Tags.Select(x => x.Name).Contains(tag))).Distinct().Take(75).ToList();

All means that all of the tags should equal to one tag. And you said it contains two tags, So it's impossible.
In MSDN words:

Determines whether all elements of a sequence satisfy a condition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文