У меня есть следующий код, который использует 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 (); Я получаю «Ссылка на объект не установлена для экземпляра объекта» «Указанное приведение неверно» в строке foreach в Patients () в первый раз. Documents.Count () работает правильно и возвращает правильное количество записей из базы данных. Я также могу взять сгенерированный SQL документов и запустить его в SSMS, и результаты вернутся правильно.
В выполняемом запросе select из 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 с тем же запросом и не получил эту ошибку. Любая помощь будет принята с благодарностью.
Спасибо,
Dan
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
Итак, по-видимому, существует проблема приведения в значение bool IsDeleted. Может ли быть так, что он пытается отобразить нулевое значение в IsDeleted of Union, поскольку нет никаких результатов, возвращаемых dataContext.EMRPatientDailyNotes? Я не думаю, что это будет проблемой, так как если я просто изменю IsDeleted = e.Deleted на IsDeleted = false, ошибки не будет. Итак, кажется, что e.Deleted возвращает не-bool значение. Но как это возможно, если e.Deleted определяется как bool из кода, сгенерированного Linq To SQL, и это битовое, а не нулевое поле в базе данных SQL?