我有'分组'的问题。 在迁移到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)
答案 0 :(得分:2)
问题发生的原因是在Orchard 1.6中Orchard.Data.Repository的Table属性&lt; T&gt;以下列方式实施:
public virtual IQueryable<T> Table
{
get { return Session.Query<T>().Cacheable(); }
}
并且您无法使用Group By with Cacheable() - there is an open ticket in HNIbernate Jira
Orchard按顺序to leverage 2nd level Nhibernate cache执行Cacheable()调用。
如果你不使用也不打算在Orchard中使用这个二级缓存和相应的模块,你可以下载Orchard源代码,并在Orchard.Data.Repository&lt; T&gt;中更改Table属性的实现。到
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});
};
}
}
可能(我还没有测试过)如果可以保证包含它的程序集将晚于Orchard.Core程序集加载,可以简化MyDataModule类:
public class MyDataModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(MyRepository<>)).As(typeof(IRepository<>)).InstancePerDependency();
}
}