Linq到Nhibernate-在Select中调用方法

Linq到Nhibernate-在Select中调用方法,nhibernate,linq-to-nhibernate,Nhibernate,Linq To Nhibernate,我需要IQueryable在基于域实体的业务逻辑程序集中。我想使用自动映射器,因为有大量类似的实体 作品: _repository.GetList<AgentDto>() .Select(dto => new Agent{Login = dto.Login, Password = dto.Password}) .Where(...).ToList(); 例外情况: System.NotSupportedException was caught

我需要
IQueryable
在基于域实体的业务逻辑程序集中。我想使用自动映射器,因为有大量类似的实体

作品:

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

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: 

您需要考虑NHibernate Linq提供者是如何工作的。它不能处理你扔给它的所有东西。NHibernate的Linq提供程序将lambda表达式转换为HQL,并最终转换为SQL。它只能支持有限的表达式子集。作为表达式输入的任何内容都必须转换为SQL并在数据库引擎本身中执行

NHibernate Linq提供程序是。如果您需要使用NH Linq提供程序不支持的一些表达式,并且您认为它们可以用SQL表示,那么您可以编写自己的表达式

然而,你的情况很简单。您无需扩展NHibernate即可完成此操作。NHibernate Linq提供程序不支持您的表达式,但Linq to对象支持。只需在查询中颠倒顺序,即可按预期工作:

_repository.GetList<AgentDto>()
    .Where(...).ToList()
    .Select(dto => ToAgent(dto)).ToList();
\u repository.GetList()
.Where(…).ToList()
.Select(dto=>ToAgent(dto)).ToList();

.ToList()
之后。Where()
将执行NHibernate查询并返回
agentTo
对象的列表
。选择
方法之后,它实际上是作为Linq to对象执行的-在内存中的
agentTO
对象列表上。

我认为,如果您只需在选择之前放置Where,就可以了。

您的方法不受支持。也就是说,当NHibernate试图将“select”转换为SQL时,它不知道如何转换“ToAgent”方法。你说的第一个变体有什么问题?谢谢。是的,我知道里面的情况。我不能使用ToList()-“我需要在我的业务逻辑中使用IQueryable”。从现在起,这个问题只是为了好玩才实际出现的,我得出结论,将DAL中的DTO映射到BLL中具有IQueryable的域实体是非常复杂的。
_repository.GetList<AgentDto>()
    .Where(...).ToList()
    .Select(dto => ToAgent(dto)).ToList();