2013-01-10 36 views
0

我遇到'group by'问题。迁移到乌节1.5.1 之前,我没有任何问题,此代码:从果园1.5.1迁移到果园1.6后Linq'Group by'

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 
         })); 

但迁移之后,果园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

问题是在这样的代码: 公共的IQueryable GETALL() { 返回_rateRepository.Table; } 正如你所看到的我得到的数据为IQueryable,我不知道它为什么在1.5.1上工作,并没有在1.6上工作。所以我在我的代码中添加了'.ToArray()',问题解决了: –

+0

public IList ListCatCurPer() {var list =(from from GetAll()from ToArray() group r by new {r .FormulaCatId,r.InputPeriodId,r.CurrencyId} 到GRP 选择(新CatCurPerViewModel { FormulaCatId = grp.Key.FormulaCatId, InputPeriodId = grp.Key.InputPeriodId, CurrencyId = grp.Key.CurrencyId }) ); return list.ToArray();} –

+0

那么...... ToArray()解决了“问题”意味着你现在从数据库加载_all_ RateRecords。 –

回答

2

问题发生,因为在果园1.6的Orchard.Data.Repository <表属性Ť>通过以下方式被实现:

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中的Table属性的实现<T>到

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类可以被简化,如果你能保证它包含装配将比果园加载后。核心组件:

public class MyDataModule : Autofac.Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterGeneric(typeof(MyRepository<>)).As(typeof(IRepository<>)).InstancePerDependency(); 
    } 
}