如何在ADO.NET Entity Framework中使用预先加载对相关实体进行排序

时间:2009-06-15 14:31:57

标签: entity-framework ado.net entity

问候,

考虑到Northwind示例表Customers,Orders和OrderDetails,我想急切加载与上述表相对应的相关实体,但我需要在获取实体之前对数据库中的子实体进行排序。

基本情况:

var someQueryable = from customer in northwindContext.Customers.Include("Orders.OrderDetails") 
select customer;

但是我还需要在数据库端对Orders和OrderDetails进行排序(在将这些实体提取到内存之前)与这些表上的一些随机列相关。是否有可能没有一些投影,就像它在T-SQL中一样?解决方案是使用e-SQL还是LINQ to Entities无关紧要。我在网上搜索但我对我找到的答案不满意,因为他们主要涉及将数据投影到某个匿名类型,然后重新查询匿名类型以按照您喜欢的顺序获取子实体。同样使用CreateSourceQuery()对我来说似乎不是一个选项,因为我需要获取数据,因为它在数据库端,通过急切加载但只是通过订购子实体。那就是我想在执行任何查询之前执行“ORDER BY”,然后按照我想要的顺序获取实体。提前感谢任何指导。作为一个个人注释,请原谅直接语言,因为我有点生气,即使与Linq to SQL(他们似乎慢慢走开)相比,微软也因为这种不成熟的形式发布了EF。我希望这个EF的东西会更好,并且在.NET FX 4.0的发布版本中没有明显的错误。

3 个答案:

答案 0 :(得分:8)

实际上我Tip正好解决了这个问题。

不支持对相关实体进行排序,但使用投影方法Craig显示 AND 依赖于名为'Relationship Fixup'的内容,您可以获得非常类似的工作:

如果你这样做:

var projection = from c in ctx.Customers
                 select new {
                       Customer = c, 
                       Orders = c.Orders.OrderByDescending( 
                                 o => o.OrderDate 
                             )
                 };

foreach(var anon in projection )
{
   anon.Orders //is sorted (because of the projection)
   anon.Customer.Orders // is sorted too! because of relationship fixup
}

这意味着如果你这样做:

var customers = projection.AsEnumerable().Select(x => x.Customer);

您将拥有已排序的客户!

请参阅提示以获取更多信息。

希望这有帮助

亚历

答案 1 :(得分:2)

你混淆了两个不同的问题。第一个是如何在数据库中实现实体,第二个是如何检索有序列表。 EntityCollection类型不是有序列表。在您的示例中,customer.Orders是一个EntityCollection。

另一方面,如果你想以特定顺序获得一个列表,你当然可以这样做;它只是不能在EntityCollection类型的属性中。例如:

from c in northwindContext.Customers
orderby c.SomeField
select new {
    Name = c.Name,
    Orders = from o in c.Orders
             orderby c.SomeField
             select new {
                SomeField = c.SomeField
             }
}

请注意,没有对Include的调用。因为我在预测,所以没必要。

实体框架可能无法以您期望的方式工作,来自LINQ to SQL背景,但它确实有效。在你明白之前要小心谴责它;决定它不起作用将阻止你了解它是如何工作的。

答案 2 :(得分:0)

谢谢你们俩。我知道我可以使用投影来实现我想要的但我认为可能有一种简单的方法可以做到这一点,因为在T-SQL世界中,完全可以使用一些嵌套查询(或连接)和顺序。另一方面,关注点分离是合理的,我们现在处于实体域中,所以我将使用你们两个推荐的方式,但我必须承认通过使用AssociateWith在LINQ to SQL中实现这个更容易和更清晰。

亲切的问候。