2011-09-16 58 views
2

我知道這可以很容易地在數據庫的兩次命中中完成,但我一直在嘗試使用單個LINQ語句通過ID加載訂單,它的訂單項,翻譯他們在同一時間視圖模型對象:在單個LINQ語句中加載父項及其子項記錄

var query = from orderLine in db.PurchaseOrderLines 
      where orderLine.PurchaseOrderId == id 
      orderby orderLine.Id 
      group orderLine by orderLine.PurchaseOrder into grouped 
      select new PurchaseOrderViewModel 
      { 
       Id = grouped.Key.Id, 
       PlacedDateTime = grouped.Key.PlacedDateTime, 
       Reference = grouped.Key.OrderReference, 
       StatusId = grouped.Key.PurchaseOrderStatusId, 
       Status = grouped.Key.PurchaseOrderStatus.Description, 
       Supplier = grouped.Key.Supplier.Name, 
       SupplierId = grouped.Key.SupplierId, 
       OrderLines = grouped.Select(row => new PurchaseOrderLineViewModel 
       { 
        Id = row.Id, 
        PartNumber = row.Product.PartNumber, 
        ProductDescription = row.Product.Description, 
        Quantity = row.Quantity 
       }) 
      }; 

然而,query類型爲System.Data.Objects.ObjectQuery<...PurchaseOrderViewModel>,並試圖重複的結果拋出一個異常:

System.InvalidOperationException was unhandled by user code 
    Message=Sequence contains no elements 
    Source=System.Core 
    StackTrace: 
     at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source) 
     at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable`1 sequence) 
     at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot) 
     at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression) 
     at System.Linq.Queryable.Single[TSource](IQueryable`1 source) 
     at MyApp.Controllers.PurchaseOrderController.Details(Int32 id) in E:\Code\WCs\MyApp\MyApp\Controllers\PurchaseOrderController.cs:line 69 
     at lambda_method(Closure , ControllerBase , Object[]) 
     at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) 
     at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
     at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
     at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() 
     at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    InnerException: 

我在做什麼錯?我會犯這個錯誤嗎?

非常感謝提前。

回答

0

您有幾個選項可以強制在LINQ-to-SQL中進行加載。不知道你是如何執行你的查詢,或者你是否正在實現分頁等等,這很難說。

我想嘗試(現有查詢還在裏面)的第一件事就是簡單地迫使OrderLines到一個新的列表執行查詢時,就像這樣:

OrderLines = grouped.Select(row => new PurchaseOrderLineViewModel 
{ 
    Id = row.Id, 
    PartNumber = row.Product.PartNumber, 
    ProductDescription = row.Product.Description, 
    Quantity = row.Quantity 
}).ToList() 

如果一切正常,這很簡單。

另一種方法是使用DataLoadOptions類。這是在LINQ-to-SQL中實現急切加載的常用方式。

var loadOptions = new DataLoadOptions(); 
loadOptions.LoadWith<PurchaseOrder>(p => p.PurchaseOrderLines); 
db.LoadOptions = loadOptions; 

唯一的問題是您需要在使用上下文之前設置datacontext的LoadOptions屬性。如果以推薦的方式使用上下文(短期,每個操作的實例),這應該不成問題,但該使用模式看起來並不像預期的那樣普遍。如果你創建一個數據上下文並傳遞它或掛上它,那麼這可能會導致你的問題。

相關問題