【问题标题】:Add a many-to-one predicate to a LINQ-to-SQL query向 LINQ-to-SQL 查询添加多对一谓词
【发布时间】:2014-03-17 09:16:24
【问题描述】:

如何过滤相关多对多表上的IQueryable<T> LINQ-to-SQL 查询?例如,给定一个IQueryable<Product>,其中每个Product 都有许多标签存储在相关的ProductTags 表中,我想过滤一个或多个标签的关联。

Product 上的文档存储或逗号分隔值会使这更简单,但数据存储在非规范化的 SQL 表中。

对于加分,如果ProductTags 表只是一个映射表,我还需要从Tags 表中检索数据怎么办?

这是架构的样子:

Products <-> ProductTags <-> Tags

更新:看来我要过滤against an EntitySet&lt;T&gt;

【问题讨论】:

    标签: c# linq-to-sql many-to-many where-clause


    【解决方案1】:

    如果你有一个标签名称列表,比如tagNames,你可以这样做:

    var query = from p in Products
                from t in p.ProductTags.Select(pc => pc.Tag)
                where tagNames.Contains(t.TagName)
                select new { p.ProductName, t.TagName };
    

    这将为您提供至少具有tagNames 中的一个标签的所有Product,您可以从ProductTag 中选择数据。

    请注意,这不一定是不同的产品列表。

    如果标签直接存储在ProductTags中,则查询变为

    var query = from p in Products
                from t in p.ProductTags
                where tagNames.Contains(t.TagName)
                select new { p.ProductName, t.TagName };
    

    【讨论】:

    • 这会生成什么 SQL?预期的子查询?是否避免了 N+1 查询?
    • 这将产生一个子查询。但是,例如,如果您只使用select 产品,然后访问它们的标签,您将得到 n+1。为防止这种情况发生,您应该使用 DataLoadOptions。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    相关资源
    最近更新 更多