Linq To Sql - 将复杂查询重构为较小的部分会抛出NullReferenceException

时间:2009-11-23 21:21:57

标签: linq linq-to-sql

我有一个非平凡的Linq To Sql查询,我试图将其分解为可读性/进一步过滤/重用。

重构的代码如下所示,其中 ids 是为抓取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;

'ids'是IOrderedQueryable< csExtendedQAIncident_Docs>它本身有许多标准和嵌套子查询(即包含在SQL服务器上被转换为EXISTS样式查询的包含)

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

当查询被提取到它自己的变量中时,查询在运行时死于SqlFactory.Member的NullReferenceException(下面的部分堆栈跟踪)

  

System.NullReferenceException:未将对象引用设置为对象的实例。      在System.Data.Linq.SqlClient.SqlFactory.Member(SqlExpression expr,MemberInfo成员)      在System.Data.Linq.SqlClient.QueryConverter.VisitMemberAccess(MemberExpression ma)      at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)      在System.Data.Linq.SqlClient.QueryConverter.Visit(表达式节点)      在System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)      在System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)      at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)      在System.Data.Linq.SqlClient.QueryConverter.Visit(表达式节点)      在System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)      在

我怀疑这是Linq到Sql的查询评估过程中的一个错误 - 但是想知道是否有其他人可能遇到过这样的问题?

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

注意:请记住,这个查询,尽管有点长,但实际上并不是SPROC在此场景中的一个很好的选择(特别是因为我们在这里遇到了SQL 2000并且无法参数化TOP :()< / p>

修改:找到另一个对未解决的非常类似问题的引用http://www.eggheadcafe.com/software/aspnet/31934404/linq-combined-query.aspx

Edit2 :问问你们会收到; 0我想我会把id子查询保留在这里,因为我认为它实际上并不相关(并且提到它很复杂等)。请不要责怪我的废话db设计 - 但是知道我在SQL上为这个查询工作了一点以获得可接受的性能,然后翻译成Linq To 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 个答案:

没有答案