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()から取得しようとしました。contextcustomer

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 を使用する代わりに、データベースにデータを処理させるにはどうすればよいですか?

前もって感謝します。

JP

4

2 に答える 2

1

You can try this query:

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();

Although Item and Article in the inner anonymous object are not used they will be loaded and Entity Framework's relationship fixup should set the correct navigation properties for Order.Items and Item.Article - as long as the relationships are not many-to-many and you don't use AsNoTracking.

If you want to perform this as a no-tracking query, you basically have to set the navigation properties yourself. It should be possible by moving the following additional Select between AsEnumerable() and 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 に答える