我有一个非常重要的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;