3

在使用 Entity Framework 5 Code First 检索一组数据时,我偶然发现了一个小问题。这是我的代码:

var data = context.Customers
            .Include("Orders")
            .Include("Orders.Items")
            .Include("Orders.Items.Article").ToArray();
foreach (var customer in data)
{
    customer.Orders = customer.Orders.OrderByDescending(o => o.OrderDate).ToArray();
}

这有效(哇!)。但是,我正试图摆脱它foreach,我希望数据库引擎继续负责处理数据。我该怎么做呢?

我试过这种类型的加入:

var data = from customer
           in context.Customers
           select new {
               customer.Id,
               customer.Name,
               // customer.Orders below doesn't have an Include() to include order items
               Orders = customer.Orders.OrderByDescending(b => b.OrderDate)
           };

// Translate anonymous object to actual models
var customers = new List<CustomerModel>();
foreach (var customer in data)
{
    customers.Add(new CustomerModel()
    {
        Id = customer.Id,
        Name = customer.Name,
        Orders = customer.Orders.ToArray()
    });
}

但是,正如评论所说,customer.Orders没有一种Include()方法来包含属于这些项目的项目和文章。然后我尝试从对象context而不是customer对象进入:

Orders = context.Orders.Include("Items").Where(o => o.Id == customer.Id)

但这会导致Include()无法以这种方式使用的运行时异常(在嵌套查询中?):

Method 'System.Data.Entity.Infrastructure.DbQuery`1[MyTests.Models.OrderModel] Include(System.String)' declared on type 'System.Data.Entity.Infrastructure.DbQuery`1[MyTests.Models.OrderModel]' cannot be called with instance of type 'System.Data.Objects.ObjectQuery`1[MyTests.Models.OrdersModel]'

像这样嵌套它甚至可能吗?

如何让数据库处理数据而不是foreach在我的第一个代码块中使用 a?

提前致谢。

J.P

4

2 回答 2

1

你可以试试这个查询:

List<CustomerModel> customers =
           (from customer
            in context.Customers
            select new {
                customer.Id,
                customer.Name,
                Orders = customer.Orders
                    .OrderByDescending(o => o.OrderDate)
                    .Select(o => new {
                        Order = o,
                        Items = o.Items
                            .Select(i => new {
                                Item = i,
                                Article = i.Article
                            })
                    })
           })
           .AsEnumerable()
           .Select(x => new CustomerModel
           {
               Id = x.Id,
               Name = x.Name,
               Orders = x.Orders.Select(o => o.Order).ToArray()
           })
           .ToList();

尽管ItemandArticle在内部匿名对象中没有使用,但它们将被加载,并且实体框架的关系修复Order.Items应该为and设置正确的导航属性Item.Article- 只要关系不是多对多并且您不使用AsNoTracking.

如果您想将此作为无跟踪查询执行,则基本上必须自己设置导航属性。通过在和Select之间移动以下附加内容应该是可能的:AsEnumerable()Select(...)

           // .AsEnumerable()
           .Select(x => new {
               Id = x.Id,
               Name = x.Name,
               Orders = x.Orders.Select(y => {
                   y.Order.Items = y.Items.Select(z => {
                       z.Item.Article = z.Article;
                       return z.Item;
                   }).ToArray();
                   return y;
               })
           })
           // .Select(x => new CustomerModel ...
于 2013-08-09T18:41:29.357 回答
0

这应该适合你:

var os = new DbContext().Orders;

var data = from customer
       in context.Customers
       select new {
           customer.Id,
           customer.Name,

           Orders = os.Include("Items").Include("Items.Article")
               .Where(o => o.CustomerId == id)
               .OrderByDescending(b => b.DatumAangemaakt)
       };
于 2013-08-06T11:56:03.287 回答