我知道这可以通过对数据库的两次点击轻松完成,但我一直在尝试使用单个LINQ语句按ID加载订单及其订单项,同时将它们转换为ViewModel对象: / p>
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 :(得分: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属性。如果您以推荐的方式使用上下文(短期,每个操作的实例),这应该不是问题,但是这种使用模式似乎并不像预期的那样普遍。如果您创建一个datacontext并传递它或挂起它,那么这可能会导致您遇到问题。