我想将每个组选择为自定义类,将每个项目选择为另一个自定义类
我是这样做的:
_notificationsManager
.GetUserNotifications(_repositoryNotifications, _memberShipProvider)
.GroupBy(x => x.Category)
.Select(g => new NotificationsGroupData {
Name = g.Key,
Notifications = g.Take(3).Select(s => new NotificationData {
Category = g.Key,
Text = s.Text,
Time = DateTime.Now.Subtract(s.Time)
})
})
NotificationsGroupData:
public class NotificationsGroupData
{
public string Name { get; set; }
public IEnumerable<NotificationData> Notifications { get; set; }
}
和NotificationData:
public class NotificationData
{
public virtual TimeSpan Time { get; set; }
public virtual string Category { get; set; }
public virtual string Text { get; set; }
}
但是当我试图创建循环时,我收到错误: 该方法或操作未实现。
在这一行:
@foreach (var group in Model.Notifications)
我该如何解决?
Uodate: 我将代码更新为:
_notificationsManager.GetUserNotifications(_repositoryNotifications, _memberShipProvider)
.GroupBy(x => x.Category)
.Select(g => new
{
Name = g.Key,
Notifications =
g.OrderBy(o => o.Time)
.Take(3)
.Select(s => new
{
Category = g.Key,
s.Text,
s.Time
})
}).AsEnumerable().Select(g => new NotificationsGroupData
{
Name = g.Name,
Notifications = g.Notifications
.Select(s => new NotificationData
{
Category = g.Name,
Text = s.Text,
Time = now - s.Time
})
})
这里有错误:
The method or operation is not implemented.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NotImplementedException: The method or operation is not implemented.
Source Error: @foreach (var group in Model.Notifications)
Stack Trace:
[NotImplementedException: The method or operation is not implemented.] NHibernate.Linq.GroupBy.NonAggregatingGroupByRewriter.FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel) +608 NHibernate.Linq.GroupBy.NonAggregatingGroupByRewriter.ReWrite(QueryModel queryModel) +598 NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root) +126 NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory) +208 NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory) +51 NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) +100 NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) +74 NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) +53 NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters) +320 NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow) +188 NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression) +164 NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery) +152 NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
+70 NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression) +59 Remotion.Linq.QueryableBase`1.GetEnumerator() +128 System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +61 ASP._Page_Views_Layout_Notifications_cshtml.Execute() in d:\Dev\Projects\ADDE\ADDE\Views\Layout\Notifications.cshtml:21 System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +197 System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +103 System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +88 System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235 System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
+291 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13 System.Web.Mvc.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17()
+23 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +245 System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
+22 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +176 System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20()
+75 System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +99 System.Web.Mvc.Async.WrappedAsyncResult`1.End()
+50 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
+31 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.Mvc.<>c__DisplayClassa.<EndProcessRequest>b__9() +22 System.Web.Mvc.<>c__DisplayClass4.<Wrap>b__3() +10 System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +27 System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Action action) +64 System.Web.Mvc.ServerExecuteHttpHandlerAsyncWrapper.EndProcessRequest(IAsyncResult result) +71 System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1464
[HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.] System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +3033503 System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +76 System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +28 System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +19 System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +463 System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper htmlHelper, String actionName, String controllerName) +35 ASP._Page_Views_Shared__Layout_cshtml.Execute() in d:\Dev\Projects\ADDE\ADDE\Views\Shared\_Layout.cshtml:33 System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +197 System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +103 System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +88 System.Web.WebPages.<>c__DisplayClass7.<RenderPageCore>b__6(TextWriter writer) +233 System.Web.WebPages.HelperResult.WriteTo(TextWriter writer) +10 System.Web.WebPages.WebPageBase.Write(HelperResult result) +71 System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body) +64 System.Web.WebPages.WebPageBase.PopContext() +246 System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +95 System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235 System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
+291 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13 System.Web.Mvc.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17()
+23 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +245 System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
+22 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +176 System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20()
+75 System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +99 System.Web.Mvc.Async.WrappedAsyncResult`1.End()
+50 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25 System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
+31 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+9629708 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
答案 0 :(得分:1)
我怀疑问题可能出现在DateTime.Now.Subtract(s.Time)
部分,可能与您使用NotificationsGroupData
相关联。
我建议您更改查询以简单地获取所需的所有数据而不进行大量处理,然后使用AsEnumerable
在本地执行更复杂的工作。如下所示:
// Use a single common idea of "now", don't re-evaluate each time
var now = DateTime.Now;
var query = _notificationsManager
.GetUserNotifications(_repositoryNotifications, _memberShipProvider)
.GroupBy(x => x.Category)
.Select(g => new {
Name = g.Key,
Notifications = g.Take(3)
.Select(s => new {
Text = s.Text,
Time = s.Time
})
})
.AsEnumerable() // Force local evaluation for final step
.Select(g => new NotificationsGroupData {
Name = g.Name,
Notifications = g.Notifications
.Select(s => new NotificationData {
Category = g.Name,
Text = s.Text,
Time = now - s.Time
})
});
编辑:好的,因为仍然存在问题,你可以尝试在进程中进行所有后分组:
var now = DateTime.Now;
var query = _notificationsManager
.GetUserNotifications(_repositoryNotifications, _memberShipProvider)
.GroupBy(x => x.Category)
.AsEnumerable() // Force local evaluation for final step
.Select(g => new NotificationsGroupData {
Name = g.Key,
Notifications = g.Take(3)
.Select(s => new NotificationData {
Category = g.Key,
Text = s.Text,
Time = now - s.Time
})
});
请注意,这远非想法 - 它会从数据库中提取所有属性,而不仅仅是您想要的属性。 (而不仅仅是前三个 - 尽管“第一个”也依赖于排序,这在我们可以看到的任何地方都没有指定。)可能这是你需要回退到SQL的情况之一,但它确实听起来像NHibernate可能会为你做更多......
答案 1 :(得分:1)
NHibernate无法将您的查询转换为sql。最快的解决方案是将你的选择声明放在内存集合中,而不是传递给NHibernate。试试这个:
_notificationsManager
.GetUserNotifications(_repositoryNotifications, _memberShipProvider)
.GroupBy(x => x.Category)
.ToList()
.Select(g => new NotificationsGroupData {
Name = g.Key,
Notifications = g.Take(3).Select(s => new NotificationData {
Category = g.Key,
Text = s.Text,
Time = DateTime.Now.Subtract(s.Time)
})
})
另一个选择是在HQL \ SQL上编写查询并将其传递给NHibernate,因此您将从数据库中提取必要数量的数据,然后将其映射到您的自定义实体。