LINQ基于与子元素的匹配返回元素

时间:2017-01-06 22:21:10

标签: c# entity-framework linq

我希望这个标题有道理。

我试图生成一个LINQ查询,该查询返回子对象的子对象的所有元素,当它们与父元素上的属性不匹配时。

希望我没有因为这种描述而迷失你。我认为一个具体的例子可能有助于解释我试图做的事情。

我有三个班级和一个枚举:

public class Studio
{
    public int StudioId { get; set; }
    public string StudioName { get; set; }
    public Style Style { get; set; }

    public virtual ICollection<Designer> Designers { get; set; }
}

public class Designer
{
    public int DesignerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int StudioId { get; set; }

    public virtual Studio Studio { get; set; }
    public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
    public int DesignerId { get; set; }
    public Style ProductStyle { get; set; }

    public virtual Designer Designer { get; set; }
}

public enum Style { Classic, Preppy, Modern, Punk, Goth }

每个工作室的总体Style,每个Product都有自己的风格。在某些情况下Product可能会显示Studio,但风格理念不匹配。

我是否可以生成LINQ个查询,以便返回IEnumberable<Product> ProductsStudio public IEnumerable<Product> GetProductsWithOutsideStyles(Studio studio) { List<Product> products = new List<Product>(); foreach (Studio s in StudioContext.Studios.Where(s => s == studio)) { foreach(Designer d in s.Designers) { foreach(Product p in d.Products) { if (p.ProductStyle != s.Style) products.Add(p); } } } return products; } 哪个不匹配?

我已经创建了一个可以工作的三重嵌套循环,但我希望能帮助将它转换为LINQ语句(使用点表示法):

{{1}}

3 个答案:

答案 0 :(得分:2)

您可以通过您设置的导航属性访问属于Studio的产品。然后,您可以轻松检查Product.ProductStyleStudio.Style之间是否存在不匹配:

from s in context.Studios
where s.StudioId == studio.StudioId
from d in s.Designers
from p in d.Products
where p.ProductStyle != s.Style
select p

顺便说一句,您必须按ID找到Studio。 EF不允许您在LINQ查询中使用studio变量。

答案 1 :(得分:1)

尝试:

 var products=studios.SelectMany(s => s.Designers
            .SelectMany(d => d.Products.Where(p => p.ProductStyle != s.Style)))
                .ToList();

答案 2 :(得分:1)

考虑使用带有多个from语句的SQL样式LINQ语法,使用&#34;嵌套&#34;来创建查询。列表

(相当于.SelectMany()扩展方法)

var products =
        from s in StudioContext.Studios.Where(s => s == studio)
        from d in s.Designers
        from p in d.Products
        where p.ProductStyle != s.Style
        select p;

扩展方法也有效;但对于嵌套列表,我个人发现SQL风格的语法更清晰(更具可读性)来表达你的意图。当存在多个嵌套级别时,.SelectMany可能稍微不那么清晰。