2

IQueryableドメインエンティティに基づくビジネスロジックアセンブリの内部が必要です。類似のエンティティが大量にあるため、この目的で自動マッパーを使用したいと思います。

作品:

_repository.GetList<AgentDto>()
        .Select(dto => new Agent{Login = dto.Login, Password = dto.Password})
        .Where(...).ToList();

動作しません(Where前に(別のアセンブリ)を配置できませんでしたSelect):

_repository.GetList<AgentDto>()
        .Select(dto => ToAgent(dto))
        .Where(...).ToList();

private Agent ToAgent(AgentDto dto)
    {
        return new Agent{Login = dto.Login, Password = dto.Password};
    }

例外:

System.NotSupportedException was caught
  Message=CustomerInfo.Domain.Support.Agent ToAgent(CustomerInfo.DAL.DTO.AgentDto)
  Source=NHibernate
  StackTrace:
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression(Expression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMemberExpression(MemberExpression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression(Expression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression(Expression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression(Expression expression)
       at NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.Visit(Expression expression, VisitorParameters parameters)
       at NHibernate.Linq.Visitors.QueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
       at Remotion.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
       at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
       at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
       at NHibernate.Linq.Visitors.QueryModelVisitor.Visit()
       at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
       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.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, 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.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
       at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
       at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
       at System.Linq.Queryable.Count[TSource](IQueryable`1 source, Expression`1 predicate)
       at CustomerInfo.BLL.Authentication.AgentManagementService.ValidateAgent(String agentLogin, String password) in D:\Projects\CustomerInfo\CustomerInfo.BLL\Authentication\AgentManagementService.cs:line 49
  InnerException: 
4

2 に答える 2

5

NHibernate Linq プロバイダーがどのように機能するかを考える必要があります。あなたが投げたものすべてを処理することはできません。NHibernate の Linq プロバイダーは、ラムダ式を HQL に変換し、最終的に SQL に変換します。サポートできる式のサブセットは限られています。式として入力するものはすべて、SQL に変換可能で、データベース エンジン自体で実行できる必要があります。

NHibernate Linq プロバイダーは拡張可能です。NH Linq プロバイダーでサポートされていない式を使用する必要があり、SQL で表現できると思われる場合は、独自のextensionを作成できます。

ただし、ケースは非常に単純です。それを行うために NHibernate を拡張する必要はありません。NHibernate Linq プロバイダーは式をサポートしていませんが、Linq to objects はサポートしています。クエリの順序を逆にするだけで、期待どおりに機能するはずです。

_repository.GetList<AgentDto>()
    .Where(...).ToList()
    .Select(dto => ToAgent(dto)).ToList();

.ToList()after.Where()は NHibernate クエリを実行し、AgentDtoオブジェクトのリストを返します。.Selectその後のメソッドは、実際にはオブジェクトへのLinqとして実行されます-AgentDtoメモリ内のオブジェクトのリスト上で。

于 2012-08-22T16:44:29.843 に答える