我对group by有一个问题。在迁移到Orchard 1.5.1之前,这段代码没有任何问题:
var list = (from r in GetAll()
group new { r.FormulaCatId, r.InputPeriodId, r.CurrencyId } by new { r.FormulaCatId, r.InputPeriodId, r.CurrencyId }
into grp
select (new CatCurPerViewModel
{
FormulaCatId = grp.Key.FormulaCatId,
InputPeriodId = grp.Key.InputPeriodId,
CurrencyId = grp.Key.CurrencyId
}));
但是在迁移到Orchard 1.6之后出现了这个问题:
2013-01-10 15:01:25,704 [7] Orchard.Exceptions.DefaultExceptionPolicy - An unexpected exception was caught
System.NotImplementedException: The method or operation is not implemented.
at NHibernate.Linq.CacheableExpressionNode.Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
at Remotion.Linq.Parsing.Structure.IntermediateModel.ExpressionResolver.GetResolvedExpression(Expression unresolvedExpression, ParameterExpression parameterToBeResolved, ClauseGenerationContext clauseGenerationContext)
at Remotion.Linq.Parsing.Structure.IntermediateModel.GroupByExpressionNode.<>c__DisplayClass1.<GetResolvedKeySelector>b__0(ExpressionResolver r)
at Remotion.Linq.Parsing.Structure.IntermediateModel.ResolvedExpressionCache`1.GetOrCreate(Func`2 generator)
at Remotion.Linq.Parsing.Structure.IntermediateModel.GroupByExpressionNode.CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
at Remotion.Linq.Parsing.Structure.IntermediateModel.ResultOperatorExpressionNodeBase.ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
at Remotion.Linq.Parsing.Structure.IntermediateModel.MethodCallExpressionNodeBase.Apply(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
at Remotion.Linq.Parsing.Structure.QueryParser.ApplyAllNodes(IExpressionNode node, ClauseGenerationContext clauseGenerationContext)
at Remotion.Linq.Parsing.Structure.QueryParser.GetParsedQuery(Expression expressionTreeRoot)
at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory)
at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
at Remotion.Linq.QueryableBase`1.GetEnumerator()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at SAS.Core.Services.RateService.ListCatCurPer()
at SAS.Core.Controllers.RatesAdminController.Index()
at lambda_method(Closure , ControllerBase , Object[] )
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__DisplayClass13.<InvokeActionMethodWithFilters>b__10()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
问题发生是因为在orchard 1.6中,orchard . data . repository
public virtual IQueryable<T> Table
{
get { return Session.Query<T>().Cacheable(); }
}
和你不能使用groupby与Cacheable() -有一个开放的票在hnberate Jira
Orchard调用Cacheable()是为了利用第二级Nhibernate缓存。
如果你不使用或者不打算在Orchard中使用这个第二级缓存和相应的模块,你可以下载Orchard的源代码,并在Orchard. data . repository
public virtual IQueryable<T> Table
{
get { return Session.Query<T>(); }
}
这将解决您的问题。
或者如果你不想改变Orchard源,你可以创建你自己的通用存储库类,并将它连接到DependencyContainer(默认情况下Orchard自带Autofac)。下面是Autofac 2.6.3.862:
public class MyRepository<T> : Orchard.Data.Repository<T> where T:class
{
public MyRepository(ISessionLocator sessionLocator) : base(sessionLocator)
{
}
public override System.Linq.IQueryable<T> Table
{
get { return Session.Query<T>(); }
}
}
public class MyDataModule : Autofac.Module
{
protected override void AttachToComponentRegistration(Autofac.Core.IComponentRegistry componentRegistry, Autofac.Core.IComponentRegistration registration)
{
base.AttachToComponentRegistration(componentRegistry, registration);
Type limitType = registration.Activator.LimitType;
if (!limitType.IsGenericType || limitType.GetGenericTypeDefinition() != typeof (Repository<>)) return;
var epamRepoTye = typeof(MyRepository<>).MakeGenericType(limitType.GetGenericArguments());
registration.Activating += (s, e) =>
{
var locator = e.Context.Resolve<ISessionLocator>();
e.Instance = Activator.CreateInstance(epamRepoTye, new object[] {locator});
};
}
}
可能(我还没有测试过这个)MyDataModule类可以简化,如果你能保证包含它的程序集将加载晚于Orchard。核心组件:
public class MyDataModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(MyRepository<>)).As(typeof(IRepository<>)).InstancePerDependency();
}
}