2013-01-10 1 views
0

'group by'에 문제가 있습니다. 마이그레이션 1.5.1 과수원에 전에,이 코드에 어떤 문제가되지 않았다Linq 'Group by'후 Orchard 1.5.1에서 Orchard 1.6으로 마이그레이션

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 = (GetAll()에서 r부터 ToArray() group r by new {r GRP 선택에 .FormulaCatId, r.InputPeriodId, r.CurrencyId} (새 CatCurPerViewModel { FormulaCatId = grp.Key.FormulaCatId, InputPeriodId = grp.Key.InputPeriodId, CurrencyId = grp.Key.CurrencyId })); return list.ToArray();} –

+0

음 ... ToArray()로 "문제 해결"은 이제 데이터베이스에서 _all_ RateRecords를로드한다는 것을 의미합니다. –

답변

2

문제가 과수원 때문에 발생

public virtual IQueryable<T> Table 
    { 
     get { return Session.Query<T>().Cacheable(); } 
    } 

및 요 : 1.6 Orchard.Data.Repository <의 표 속성 T >는 다음과 같은 방식으로 구현된다 캐시 가능() - there is an open ticket in HNIbernate Jira

과 함께 Group By를 사용하십시오. Orchard는 해당 Cacheable() 호출을 to leverage 2nd level Nhibernate cache으로 수행합니다.

이 2 수준 캐시와 해당 모듈을 오차드에서 사용하지 않을 경우 Orchard 소스 코드를 다운로드하고 Orchard.Data.Repository에서 테이블 속성 구현을 변경하십시오. <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 클래스를 단순화 할 수있다 .Core 어셈블리 :

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