代码之家  ›  专栏  ›  技术社区  ›  Ethan J. Brown

linq to sql-将复杂查询重构为更小的部分会引发nullreferenceexception

  •  2
  • Ethan J. Brown  · 技术社区  · 16 年前

    我有一个非常重要的linq-to-sql查询,为了可读性/进一步的过滤/重用,我正试图将它分解成几部分。

    重构后的代码如下所示 身份证 是为获取ID而执行的子查询。

     var results = from solution in context.csExtendedQAIncident_Docs
                    join solutionText in context.csNTexts
                       on solution.chIdNo equals solutionText.chIdNo
                    where solutionText.chColumnId == "Solution"
                    //this is a very complicated subquery that returns a short list of the ids we need
                    && (ids).Select(s => s.chIdNo)
                    //the TOP query portion - applied to just the ids
                    .Take(count ?? Settings.Current.WCFServices().Output.HomePage.MaxRows)
                    .Contains(solution.chIdNo)
                    select solution;
    

    “id”是一个iorderedqueryable<csextendedqaaincident\u docs>,它本身有许多条件和嵌套的子查询(即包含转换为SQL Server上现有样式的查询)

    无论如何,这里的问题是,当在上面的结果查询中包含完整的子查询时,查询就可以正常工作。

    当查询被拉到自己的变量中时,查询在运行时终止,在sqlfactory.member处出现一个nullreferenceexception(下面是部分堆栈跟踪)

    system.nullreferenceexception:对象引用未设置为对象的实例。 在system.data.linq.sqlclient.sqlfactory.member(sqlexpression expr,memberinfo成员) 在system.data.linq.sqlclient.queryconverter.visitMemberAccess(memberExpression MA) 在system.data.linq.sqlclient.queryconverter.visitinner(表达式节点) 在system.data.linq.sqlclient.queryconverter.visit(表达式节点) 在system.data.linq.sqlclient.queryconverter.visitexpression(expression exp) 在system.data.linq.sqlclient.queryconverter.visitmethodcall(methodcallexpression mc) 在system.data.linq.sqlclient.queryconverter.visitinner(表达式节点) 在System.Data.Linq.SqlClient.QueryConverter.Visit(表达式节点) 在system.data.linq.sqlclient.queryconverter.visitexpression(expression exp) 在

    我怀疑这是Linq to Sql查询求值过程中的一个错误——但我想知道是否还有其他人遇到了这样的问题?

    我进入了框架的源代码——当然,问题是,虽然我可以找到异常的确切源代码行,但我使用的Linq程序集已经优化,我无法检查变量等。

    注意:请记住,尽管这个查询有点长,但在这个场景中,它并不是存储过程的最佳候选查询(特别是因为我们在这里停留在sql 2000上,无法参数化top:()

    编辑 :发现另一个引用了一个非常相似的问题,但一直没有解决 http://www.eggheadcafe.com/software/aspnet/31934404/linq-combined-query.aspx

    编辑2 :ask和ye会收到;0我想我会把id子查询放在外面,因为我认为它实际上并不相关(如前所述,它很复杂等等)。请不要把糟糕的数据库设计归咎于我——但要知道,为了获得可接受的性能,我在这个查询的sql上工作了一段时间,然后将其转换为linq到sql。

    var ids = from solutionIds in context.csExtendedQAIncident_Docs
              where solutionIds.iIncidentTypeId == 102094
              && solutionIds.tiRecordStatus == 1
              && solutionIds.iLanguage == 102074
              && null != solutionIds.chIdNo
              && (from openTo in context.csOpenTos
                  where onyxIdentity.GetDocumentAccessLevels().Union(new[] { "BUSG5" }).ToArray().Contains(openTo.vchOpenTo)
                  select openTo.chIdNo
                 ).Distinct().Contains(solutionIds.chIdNo)
              && (from solutionProductAssocation in context.csProductDocs
                  where (from allowedProduct in context.KB_User_Allowed_Products
                         where allowedProduct.UserId == userId
                         select allowedProduct.ModelCode
                        ).Contains(solutionProductAssocation.chModelCd)
                  select solutionProductAssocation.chIdNo).Distinct().Contains(solutionIds.chIdNo)
              orderby solutionIds.dtUpdateDate descending
              select solutionIds;
    
    0 回复  |  直到 16 年前