我有以下代码,它使用Linq to SQL在.NET 4.0中与SQL Server 2008 R2服务器交互:
public void Patients()
{
var documents = GetEMRDocumentsByPatientId("231966");
if (documents.Count() > 0)
{
foreach (var doc in documents)
{
Console.WriteLine(doc.PatientId);
}
}
}
public static IQueryable<EMRDocument> GetEMRDocumentsByPatientId(string inPatientId)
{
return GetEMRDocuments().Where(d => String.Equals(d.PatientId, inPatientId));
}
public static IQueryable<EMRDocument> GetEMRDocuments()
{
var dataContext = InitializeDataContext();
IQueryable<EMRDocument> retVal = null;
retVal = (from e in dataContext.EMREvaluations
select new EMRDocument
{
PatientId = e.PatientId,
IsDeleted = e.Deleted,
}).Union(
from e2 in dataContext.EMRPatientDailyNotes
select new EMRDocument
{
PatientId = e2.PatientID,
IsDeleted = false,
});
return retVal;
}
该应用程序的启动调用了Patients()方法; 在第一次进入Patients()方法时,在foreach循环行上收到“对象引用未设置为对象实例”的错误或“指定的强制转换无效”的错误。documents.Count()函数能够正确地返回数据库中记录的正确数目。我还可以在SSMS中运行documents生成的SQL查询,结果也是正确的。
在运行的查询中,dataContext.EMRPatientDailyNotes的select和from语句没有返回任何记录,因为该表中不存在PatientId为231966的记录。
在GetEMRDocuments()方法中,如果注释掉两个select语句中的IsDeleted = e.Deleted和IsDeleted = false,则以下所有代码都会执行而不会出错。如果将IsDeleted = e.Deleted改为IsDeleted = false,则该代码也会正常运行。如果删除整个Union,只运行以下内容...
retVal = (from e in dataContext.EMREvaluations
select new EMRDocument
{
PatientId = e.PatientId,
IsDeleted = e.Deleted,
});
如果没有错误,那么这段代码就会执行。此外,e.Deleted是来自数据库的bool类型,而不是bool?(可空bool)类型,而IsDeleted是bool类型。有人遇到过这种问题吗?我不知道该怎么解决。此外,我之前在使用相同的查询时使用了Linq To Entities,并没有收到此错误。非常感谢任何帮助。
谢谢, 丹
编辑: 以下是堆栈跟踪。我有一些其他代码似乎隐藏了实际的错误:
[InvalidCastException: Specified cast is not valid.]
System.Data.SqlClient.SqlBuffer.get_Boolean() +5057281
System.Data.SqlClient.SqlDataReader.GetBoolean(Int32 i) +38
Read_EMRDocument(ObjectMaterializer`1 ) +313
System.Data.Linq.SqlClient.ObjectReader`2.MoveNext() +32
ATI.TherapyConnect.Service.Patients() in C:\SVN\Application\branches\dan.cagney\ATI.TherapyConnect\Service.asmx.cs:57
ATI.TherapyConnect.Content.UserControls.Shared.Patients.MyPatientsList.BindGrid(String inSortExpression, Int32 inCurrentPage) in C:\SVN\Application\branches\dan.cagney\ATI.TherapyConnect\Content\UserControls\Shared\Patients\MyPatientsList.ascx.cs:129
ATI.TherapyConnect.Content.UserControls.Shared.Patients.MyPatientsList.Page_Load(Object sender, EventArgs e) in C:\SVN\Application\branches\dan.cagney\ATI.TherapyConnect\Content\UserControls\Shared\Patients\MyPatientsList.ascx.cs:68
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +74
System.Web.UI.Control.LoadRecursive() +146
System.Web.UI.Control.LoadRecursive() +146
System.Web.UI.Control.LoadRecursive() +146
System.Web.UI.Control.LoadRecursive() +146
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207
显然,在IsDeleted的bool值中存在转型问题。这可能是因为它正在尝试将null值映射到Union的IsDeleted中,因为从dataContext.EMRPatientDailyNotes返回了零个结果。但我认为这不是问题,因为如果我只是将IsDeleted = e.Deleted更改为IsDeleted = false,就没有错误。所以,似乎e.Deleted返回了非bool值。但是当Linq To SQL生成的代码中将其定义为bool且它是SQL数据库中的bit(不是null字段)时,这怎么可能呢?