2011-09-16 35 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属性。如果以推荐的方式使用上下文(短期,每个操作的实例),这应该不成问题,但该使用模式看起来并不像预期的那样普遍。如果你创建一个数据上下文并传递它或挂上它,那么这可能会导致你的问题。

相关问题