首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AsBooleanExpression中的NHibernate InvalidCastException,HQLTreeNode.cs中的HqlTreeNodeExtensions类

AsBooleanExpression中的NHibernate InvalidCastException,HQLTreeNode.cs中的HqlTreeNodeExtensions类
EN

Stack Overflow用户
提问于 2013-05-02 02:23:45
回答 1查看 479关注 0票数 0

:我有个问题...我选择使用NHibernate 3.3.3源代码,而不是预编译的DLL,因为我已经厌倦了NHibernate问题,并且无法调试它们(即黑盒)。我用fluent NHibernate也做了同样的事情。

我用预编译的NHibernate动态链接库测试了我为fluent NHibernate编译的源代码,它可以工作。所以我决定更进一步,用NHibernate做同样的事情。这就是它糟糕的地方:我的应用程序启动,搜索引擎vorks,等等……但是每次我尝试保存一些东西时,我在类HqlTreeNodeExtensions (在文件HQLTreeNode.cs中)的"AsBooleanExpression“方法中收到一个"NHibernate.Hql.Ast.HQLBitWiseAnd”类型的值,而不能将其转换为NHibernate.Hql.Ast.HqlBooleanExpression时,就会得到一个InvalidCastException。

为什么它可以在编译后的DLL上运行,而不能在源代码中运行?我对NHibernate的内部原理一无所知,只对c#略知一二,因为我是一名VB开发人员。

这就是它发生的地方:

代码语言:javascript
运行
复制
public static class HqlTreeNodeExtensions
{
    public static HqlExpression AsExpression(this HqlTreeNode node)
    {
        // TODO - nice error handling if cast fails
        return (HqlExpression)node;
    }

    public static HqlBooleanExpression AsBooleanExpression(this HqlTreeNode node)
    {
        if (node is HqlDot)
        {
            return new HqlBooleanDot(node.Factory, (HqlDot) node);
        }


        // TODO - nice error handling if cast fails
        return (HqlBooleanExpression)node;  <-------- RIGHT HERE - the cast fails      
    }
}

(无法为堆栈调用发布图像;将尝试将其转换为可读性文本)

有人能帮帮他吗?

非常感谢

尼科

附注:这是完整的调用堆栈: Ok;这里我们开始完整的调用堆栈:摘录自我自己的代码: All开始于行"Dim ctrlResultatsRecherche As New ResultatsRechercheClientV2...“

代码语言:javascript
运行
复制
    Private Sub RechercheClient_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles txtCodePostal.KeyDown, txtClient.KeyDown, txtRue.KeyDown, txtVille.KeyDown
        If e.KeyCode = Keys.Enter Then

            Dim bolMaibecExpress As Boolean = False

            'Récupérer le contrôle parent.
            If Not Parent Is Nothing AndAlso TypeOf Parent.Parent Is SaisieDemandeEchantillon Then
                bolMaibecExpress = TryCast(Parent.Parent, SaisieDemandeEchantillon).chkMaibecExpress.Checked
            End If

            panDetails.Controls.DisposeAndRemoveAll()
            Dim ctrlResultatsRecherche As New ResultatsRechercheClientV2(m_Session, txtClient.Text, txtCodePostal.Text, txtVille.Text, txtRue.Text, bolMaibecExpress) 
            AddHandler ctrlResultatsRecherche.ClientSelectionneV2, AddressOf RésultatsRecherche_ClientSélectionné
            panDetails.Controls.Add(ctrlResultatsRecherche)
            panDetails.Visible = True
        End If
    End Sub

然后摘自我自己的代码:在"Dim resultats = m_Session.Query(Of Client).Where(predicat.Expand).ToList“行停止。

代码语言:javascript
运行
复制
Public Sub New(ByVal session As ISession, ByVal strClient As String, ByVal strCodePostal As String, ByVal strVille As String, ByVal strRue As String, Optional ByVal MaibecExpress As Boolean = False)

    ' This call is required by the Windows Form Designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    dgvResultatsRecherche.AutoGenerateColumns = False

    m_Session = session

    Dim predicat = PredicateBuilder.False(Of Client)()
    predicat = predicat.Or(Function(x As Client) (x.Prenom.Contains(strClient) OrElse x.Nom.Contains(strClient) OrElse x.Telephone.Contains(strClient) OrElse x.Courriel.Contains(strClient) OrElse strClient = "") _
                                                And (x.Adresse.CodePostal.Contains(strCodePostal) Or strCodePostal = "") _
                                                And (x.Adresse.Ville.Contains(strVille) Or strVille = "") _
                                                And (x.Adresse.Ligne1.Contains(strRue) Or strRue = "") _
                                                And (x.MaibecExpress = MaibecExpress Or MaibecExpress = False))

    Dim resultats = m_Session.Query(Of Client).Where(predicat.Expand).ToList
    dgvResultatsRecherche.DataSource = resultats
    lblNbResultatsTrouvés.Text = String.Format("{0} résultats trouvés", resultats.Count)
    SetDataBindings()
End Sub

然后调用remotion.link.dll -> Remotion.Linq.QueryableBase.GetEnumerator() (对不起,没有代码)

然后从NHibernate.Linq.DefaultQueryProvider执行sub,在"NhLinqExpression nhLinqExpression = PrepareQuery(expression,out query,out nhQuery);“行

代码语言:javascript
运行
复制
    public TResult Execute<TResult>(Expression expression)
    {
        return (TResult) Execute(expression);
    }

然后从NHibernate.Linq.DefaultQueryProvider的"return“行执行sub

代码语言:javascript
运行
复制
    public virtual object Execute(Expression expression)
    {
        IQuery query;
        NhLinqExpression nhQuery;
        NhLinqExpression nhLinqExpression = PrepareQuery(expression, out query, out nhQuery);

        return ExecuteQuery(nhLinqExpression, query, nhQuery);
    }

然后从NHibernate.Linq.DefaultQueryProvider查询,在“PrepareQuery = Session.CreateQuery(nhLinqExpression);”行

代码语言:javascript
运行
复制
    protected NhLinqExpression PrepareQuery(Expression expression, out IQuery query, out NhLinqExpression nhQuery)
    {
        var nhLinqExpression = new NhLinqExpression(expression, Session.Factory);

        query = Session.CreateQuery(nhLinqExpression);

        nhQuery = query.As<ExpressionQueryImpl>().QueryExpression.As<NhLinqExpression>();

        SetParameters(query, nhLinqExpression.ParameterValuesByName);
        SetResultTransformerAndAdditionalCriteria(query, nhQuery, nhLinqExpression.ParameterValuesByName);
        return nhLinqExpression;
    }

然后是来自NHibernate.Impl.AbstractSessionImpl的CreateQuery sub,在"var queryPlan = GetHQLQueryPlan(queryExpression,false);“行

代码语言:javascript
运行
复制
    public virtual IQuery CreateQuery(IQueryExpression queryExpression)
    {
        using (new SessionIdLoggingContext(SessionId))
        {
            CheckAndUpdateSessionStatus();
            var queryPlan = GetHQLQueryPlan(queryExpression, false);
            var query = new ExpressionQueryImpl(queryPlan.QueryExpression, 
                                            this,
                                            queryPlan.ParameterMetadata
                                            );
            query.SetComment("[expression]");
            return query;
        }
    }

然后是NHibernate.Impl.AbstractSessionImpl的GetHQLQueryPlan sub (在返回线卡住)

代码语言:javascript
运行
复制
    protected internal virtual IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow)
    {
        using (new SessionIdLoggingContext(SessionId))
        {
            return factory.QueryPlanCache.GetHQLQueryPlan(queryExpression, shallow, EnabledFilters);
        }
    }

然后是来自NHibernate.Engine.Query.QueryPlan的GetHQLQueryPlan sub (jams at line Plan =新的HQLExpressionQueryPlan (...))

代码语言:javascript
运行
复制
    public IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow, IDictionary<string, IFilter> enabledFilters)
    {
        string expressionStr = queryExpression.Key;

        var key = new HQLQueryPlanKey(queryExpression, shallow, enabledFilters);
        var plan = (IQueryExpressionPlan)planCache[key];

        if (plan == null)
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("unable to locate HQL query plan in cache; generating (" + expressionStr + ")");
            }
            plan = new HQLExpressionQueryPlan(expressionStr, queryExpression, shallow, enabledFilters, factory);
            planCache.Put(key, plan);
        }
        else
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("located HQL query plan in cache (" + expressionStr + ")");
            }
            var planExpression = plan.QueryExpression as NhLinqExpression;
            var expression = queryExpression as NhLinqExpression;
            if (planExpression != null && expression != null)
            {
                //NH-3413
                //Here we have to use original expression.
                //In most cases NH do not translate expression in second time, but 
                // for cases when we have list parameters in query, like @p1.Contains(...),
                // it does, and then it uses parameters from first try. 
                //TODO: cache only required parts of QueryExpression
                planExpression._expression = expression._expression;
                planExpression._constantToParameterMap = expression._constantToParameterMap;
            }
        }

        return plan;
    }

然后在HQLExpressionQueryPlan中(跳过属性),在返回行:

代码语言:javascript
运行
复制
    private static IQueryTranslator[] CreateTranslators(string expressionStr, IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
    {
        IQueryTranslatorFactory2 qtFactory = new ASTQueryTranslatorFactory();

        return qtFactory.CreateQueryTranslators(expressionStr, queryExpression, collectionRole, shallow, enabledFilters, factory);
    }

然后在ASTQueryTranslatorFactory.cs中,在返回行:

代码语言:javascript
运行
复制
    public IQueryTranslator[] CreateQueryTranslators(string queryIdentifier, IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
    {
        return CreateQueryTranslators(queryExpression.Translate(factory), queryIdentifier, collectionRole, shallow,
                                      filters, factory);
    }

在QueryModelVisitor.cs中,在GenerateHqlQuery (仅摘录)中的Visitor.Visit()行//... //识别和命名查询源(Visitor.Visit queryModel);

代码语言:javascript
运行
复制
        var visitor = new QueryModelVisitor(parameters, root, queryModel) { RewrittenOperatorResult = result };
        visitor.Visit();

        return visitor._hqlTree.GetTranslation();

然后对Remotion进行了几次调用,但我没有代码...然后,在表达式中,在VisitWhereClause中,在var QueryModelVisitor.cs =...

代码语言:javascript
运行
复制
    public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
    {
        // Visit the predicate to build the query
        var expression = HqlGeneratorExpressionTreeVisitor.Visit(whereClause.Predicate, VisitorParameters).AsBooleanExpression();
        if (whereClause is NhHavingClause)
        {
            _hqlTree.AddHavingClause(expression);
        }
        else
        {
            _hqlTree.AddWhereClause(expression);
        }
    }

然后在HQLGeneratorExpressionTreeVisitor.cs中,在访问函数中,返回行:

代码语言:javascript
运行
复制
    public static HqlTreeNode Visit(Expression expression, VisitorParameters parameters)
    {
        return new HqlGeneratorExpressionTreeVisitor(parameters).VisitExpression(expression);
    }

然后,在同一文件中,行返回表达式((BinaryExpression)VisitBinaryExpression)-(仅摘录):

代码语言:javascript
运行
复制
            //...
            case ExpressionType.GreaterThan:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.Coalesce:
            case ExpressionType.ArrayIndex:
                return VisitBinaryExpression((BinaryExpression) expression);
            case ExpressionType.Conditional:
                return VisitConditionalExpression((ConditionalExpression) expression);
            case ExpressionType.Constant:
                return VisitConstantExpression((ConstantExpression) expression);
            //...

Same file,function VisitBinaryExpression,linereturn _hqlTreeBuilder.BooleanOr(lhs.AsBooleanExpression(),rhs.AsBooleanExpression()) -仅摘录

代码语言:javascript
运行
复制
            //...
            case ExpressionType.AndAlso:
                return _hqlTreeBuilder.BooleanAnd(lhs.AsBooleanExpression(), rhs.AsBooleanExpression());

            case ExpressionType.Or:
                return _hqlTreeBuilder.BitwiseOr(lhs, rhs);

            case ExpressionType.OrElse:
                return _hqlTreeBuilder.BooleanOr(lhs.AsBooleanExpression(), rhs.AsBooleanExpression());

            case ExpressionType.Add:
                if (expression.Left.Type == typeof (string) && expression.Right.Type == typeof (string))
                {
                    return _hqlTreeBuilder.MethodCall("concat", lhs, rhs);
                }
                return _hqlTreeBuilder.Add(lhs, rhs);       
            //...

最后,在HQLTreeNode.cs中,行返回(HqlBooleanExpression)节点,靠近奇怪的todo注释:

代码语言:javascript
运行
复制
public static class HqlTreeNodeExtensions
{
    public static HqlExpression AsExpression(this HqlTreeNode node)
    {
        // TODO - nice error handling if cast fails
        return (HqlExpression)node;
    }

    public static HqlBooleanExpression AsBooleanExpression(this HqlTreeNode node)
    {
        if (node is HqlDot)
        {
            return new HqlBooleanDot(node.Factory, (HqlDot) node);
        }

        // TODO - nice error handling if cast fails
        return (HqlBooleanExpression)node;
    }
}               
EN

回答 1

Stack Overflow用户

发布于 2013-05-02 02:35:54

您可能会中断抛出的异常,但如果您继续(F5),该异常将在NHibernate源代码的更高级别上处理。尽管源代码中的注释让我产生了怀疑。尝试这样做:在Visual Studio中,转到Debug > Exceptions并取消选中抛出列中Common Language Runtime Exception的复选框。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16324000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档