【问题标题】:Linq query question (one to many, child object property filter)linq查询题(一对多,子对象属性过滤器)
【发布时间】:2009-07-23 00:31:15
【问题描述】:

我对 linq 很陌生,正在努力创建查询。 我有一个“客户”表和“订单”表,一对多的关系。 如何选择那些订单描述中包含“特殊”字样的最早订单的客户?

如果最旧的订单不包含此单词,则客户不应出现在结果中。如果客户没有订单,他不应该出现在结果中。换句话说,只有那些有订单并且最早的订单中有“特殊”字样的客户才应该在那里。

希望我说的很清楚,谢谢。

【问题讨论】:

    标签: linq-to-sql


    【解决方案1】:

    public static List SampleSelect(List clients)
    {
        返回 clients.Where(c => c.Orders.Count > 0 &&
                                                   c.Orders.OrderBy(o => o.Date)
                                                .FirstOrDefault().Description.Contains("Special")).ToList();
    }

    //固定排序,感谢 Ryan Versaw

    【讨论】:

    • 这应该是升序而不是降序。
    • 是的,但那是次要的,算法正确,这一点更重要。
    • 是的,我知道这是次要的 - 这就是我评论和投票的原因:)
    • 请记住,如果没有与 where 子句匹配的客户端,FirstOrDefault 将返回 null。期待 NullReferenceExceptions。
    • 我正要提到这一点,但不确定会发生什么 - 该调用如何转换为 SQL?那个 SQL 真的会抛出异常吗?
    【解决方案2】:

    这是从您的问题中推断出的快速猜测。它可能准确也可能不准确:

    var dc = new MyDataContext();    
    var qry = from customer in dc.Customers 
              where customer.Orders.Description.Contains("special")
                 && customer.Orders.OrderDate > myMinDate 
                 && customer.Orders.OrderDate < myMaxDate 
              order by customer.Orders.OrderDate ascending 
              select customer;
    

    它应该返回按订单日期排序的客户对象,按最小和最大日期过滤。如果您不想按日期过滤,可以删除这两行。

    期望客户重复。如果您需要不重复,请添加一个 group by 子句。

    祝你好运,报告它的工作情况。 :)

    编辑:

    谢谢,Randolpho,问题是我没有 myMinDate 和 myMaxDate。我需要能够检查最旧订单的描述。我觉得我应该使用类似 where c.Orders.Where(x=>x.OrderDate.Max()) 但不能正确组合整个查询的东西。谢谢。瓦伦丁·瓦西里耶夫

    嗯...我不知道您是否想要最旧订单的客户并从中检查描述,或者您是否想要订单中包含“特殊”一词的最早订单的客户描述。

    如果您希望客户拥有最早的订单,然后想要检查描述,您应该执行以下操作:

    var qry = from customer in dc.Customers
              order by customer.Orders.OrderDate ascending
              select new 
              { 
                 CustomerData = customer, 
                 OrderDescription = customer.Orders.Description
              };
    var oldest = qry.First();
    if(oldest.OrderDescription.Contains("special"))
    {
        // do something
    }
    

    在这种情况下,最旧是一种新的匿名类型,它有两个字段,CustomerData 包含最旧订单的客户,OrderDescription 包含最旧订单的描述字段。

    另一方面,您可能需要包含“特殊”一词的最早订单。在这种情况下,您应该这样做:

    var qry = from customer in dc.Customers
              where customer.Orders.Description.Contains("special")
              order by customer.Orders.OrderDate ascending
              select customer;
    var oldestCustomerWithSpecial = qry.First();
    

    在这种情况下,描述中包含单词“special”的最旧记录的客户位于名为oldestCustomerWithSpecial 的变量中。

    我认为在 OrderDate 上使用 Max 不会对您有所帮助。使用按日期排序的 TOP 1 查询几乎总是更好。在查询上调用 First() 将做到这一点。

    【讨论】:

    • 谢谢,Randolpho,问题是我没有 myMinDate 和 myMaxDate。我需要能够检查最旧订单的描述。我觉得我应该使用类似 where c.Orders.Where(x=>x.OrderDate.Max()) 但不能正确组合整个查询的东西。谢谢。
    • 我的案子是第一个。不幸的是它没有编译,我不能在这里访问 OrderDate:order by customer.Orders.OrderDate 升序,因为 Orders 是一个集合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多