我有以下代码,它在 .NET 4.0 中针对 SQL Server 2008 R2 服务器使用 Linq to SQL:
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;
}
应用程序的启动调用Patient();我第一次在 Patient() 的 foreach 行上收到 “对象引用未设置为对象的实例”“指定的转换无效”错误。documents.Count() 有效正确并从数据库中返回正确的记录数。我还可以获取文档生成的 SQL 并在 SSMS 中运行它,并且结果正确返回。
在运行的查询中,从 dataContext.EMRPatientDailyNotes 中进行的选择不会返回任何记录,因为该表中没有 PatientId 231966 的记录。
在 GetEMRDocuments() 中,如果我在两个选择中注释掉 IsDeleted = e.Deleted 和 IsDeleted = false,则下面的整个代码将执行而不会出现错误。如果我将 IsDeleted = e.Deleted 更改为 IsDeleted = false,则代码运行时不会出现错误。如果我删除整个联盟并运行
下列...
retVal = (from e in dataContext.EMREvaluations
select new EMRDocument
{
PatientId = e.PatientId,
IsDeleted = e.Deleted,
});
...然后这段代码执行没有错误。另外,e.Deleted 是数据库中的 bool,而不是 bool?(nullable bool),而 IsDeleted 是 bool。以前有人见过此类问题吗?我不知道该怎么做才能解决这个问题。另外,我之前使用 Linq To Entities 进行相同的查询,但没有收到此错误。任何帮助将不胜感激。
谢谢,
担
EDIT:这是堆栈跟踪。我还有一些其他代码似乎隐藏了实际的错误:
[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 值存在转换问题。由于 dataContext.EMRPatientDailyNotes 没有返回结果,它是否会尝试将 null 值映射到 Union 的 IsDeleted 中?我不认为这会是问题,因为如果我只是将 IsDeleted = e.Deleted 更改为 IsDeleted = false,就不会出现错误。因此,看起来 e.Deleted 返回的是非布尔值。但是,当 e.Deleted 被定义为 Linq To SQL 生成代码中的 bool 并且它是 SQL 数据库中的一个位字段而不是 null 字段时,这怎么可能呢?