【问题标题】:Linq To SQL Specified cast is not valid error with UnionLinq To SQL Specified cast is not valid error with Union
【发布时间】:2011-11-02 15:14:34
【问题描述】:

我有以下代码在 .NET 4.0 中使用 Linq to SQL 和 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();我第一次在 Patient() 的 foreach 行收到 "Object reference not set to an instance of an object""Specified cast is not valid" 错误。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 是数据库中的布尔值,而不是布尔值?(可为空的布尔值),而 IsDeleted 是布尔值。有没有人见过这种类型的问题?我不知道该怎么做才能解决这个问题。另外,我以前使用 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 的布尔值存在转换问题。会不会是因为 dataContext.EMRPatientDailyNotes 没有返回结果,所以它试图将空值映射到 Union 的 IsDeleted 中?我认为这不是问题,因为如果我只是将 IsDeleted = e.Deleted 更改为 IsDeleted = false,则不会出现错误。因此,似乎 e.Deleted 正在返回一个非布尔值。但是,当 e.Deleted 被定义为 Linq To SQL 生成的代码中的 bool 并且它在 SQL 数据库中有点,而不是 null 字段时,这怎么可能呢?

【问题讨论】:

    标签: c# linq-to-sql


    【解决方案1】:

    我终于能够让它工作,但我不知道为什么需要我的改变。以下是我将查询更改为:

    retVal = (from e in dataContext.EMREvaluations 
                  select new EMRDocument 
                  { 
                      PatientId = e.PatientId, 
                      IsDeleted = e.Deleted == null ? false : e.Deleted, 
                  }).Union( 
                 from e2 in dataContext.EMRPatientDailyNotes 
                 select new EMRDocument 
                 { 
                     PatientId = e2.PatientID, 
                     IsDeleted = false, 
                 }); 
    

    我修改了

    IsDeleted = e.Deleted 
    

    IsDeleted = e.Deleted == null ? false : e.Deleted
    

    但是我不知道为什么需要这样做,因为 e.Deleted 在数据库中被列为布尔值(非空),那么 e.Deleted 怎么可能有空值呢?我现在将其标记为答案,但是如果有人可以告诉我为什么需要更改此代码,或者我如何在不更改此代码的情况下度过难关,我会将其标记为答案。

    谢谢, 丹

    【讨论】:

    • 这令人难以置信。我有同样的情况,这也解决了我的问题。
    【解决方案2】:

    我在下面的函数中遇到了类似的问题。它可以在 dev 中完美运行,但在生产中,在相同版本的 SQL Server 上失败,“Specified cast is not valid”。

    public IQueryable<Contract> AllContracts()
        {
            IQueryable<Contract> contracts =
                from c in DbDw().Contracts
                select c;
            return contracts;
        }
    

    DbDw() 是 Linq To Sql 数据上下文

    经过大量的摸索和反复试验,我将其修改为:

    public IQueryable<Contract> AllContracts()
        {
             return DbDw().Contracts;
        }
    

    然后它起作用了......去看看。

    【讨论】:

      【解决方案3】:

      接受的答案对我不起作用,因为我需要保留空值。

      我发现切换union的顺序解决了问题,只是不要问我为什么:

      retVal = 
          (
              from e2 in dataContext.EMRPatientDailyNotes 
              select new EMRDocument 
              { 
                  PatientId = e2.PatientID, 
                  IsDeleted = (bool?)false
              }
          )
          .Union(
              from e in dataContext.EMREvaluations 
              select new EMRDocument 
              { 
                  PatientId = e.PatientId, 
                  IsDeleted = e.Deleted
              }
          ); 
      

      【讨论】:

        猜你喜欢
        • 2020-06-05
        • 1970-01-01
        • 2012-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-12
        • 1970-01-01
        • 2011-04-26
        相关资源
        最近更新 更多