2016-09-28 66 views
1

在我的LINQ查詢的賦值部分中,我需要檢查值是否爲空,如果是,則指定默認值。返回的值類型是十進制數,當我比較爲空時,我得到警告在LINQ查詢中檢查NULL的小數點

由於類型'decimal'的值永遠不等於'null'類型,因此表達式的結果始終爲'false' 「小數?

如果我嘗試比較,看是否值是0,那麼我的錯誤

演員陣容價值型「System.Decimal」失敗,因爲物化值爲null。結果類型的泛型參數或查詢都必須使用可爲空的類型。

什麼是檢查HoursWorked2是否爲空的最佳方法,併爲其分配默認值(如果它爲空)?

編輯: 我沒有想到會需要的一切所有的代碼,但因爲有些人認爲這是在這裏需要的是所有與它的代碼:

// AJAX: /TimeOverviewGrid 
    [Route("TimeOverviewGrid", Name = "Time Overview Grid")] 
    public ActionResult TimeOverviewGrid() 
    { 
     var PayPeriod = TimeCardHelper.GetCurrentPayPeriod(); 
     var WeekBeforePayPeriod = PayPeriod.AddDays(-7); 

     try 
     { 
      var EmployeeID = EmployeeHelper.GetEmployeeID(User.Identity.Name); 

      using (var db = new JobSightDbContext()) 
      { 
       var TimeOverviewData = (from th1 in db.TimeCardHeaders 
             join e in db.Employees on th1.EmployeeID equals e.ID 
             join so1 in db.StatusOptions on th1.CurrentStatusID equals so1.ID 
             join leftth2 in db.TimeCardHeaders.Where(timeCardHeader => timeCardHeader.WeekEndingDate == PayPeriod) 
             on th1.EmployeeID equals leftth2.EmployeeID into leftjointh2 
             from th2 in leftjointh2.DefaultIfEmpty() 
             join so2 in db.StatusOptions on th2.CurrentStatusID equals so2.ID into leftjoinso2 
             from th2Final in leftjoinso2.DefaultIfEmpty() 
             where th1.WeekEndingDate == WeekBeforePayPeriod && (e.ID == EmployeeID || e.ManagerID == EmployeeID) 
             orderby e.FirstName 
             select new DashboardTimeOverviewVM() 
             { 
              EmployeeID = e.ID, 
              Employee = string.Concat(e.FirstName, " ", e.LastName), 
              WeekOfDate1 = th1.WeekEndingDate, 
              HoursWorked1 = th1.TotalHoursWorked, 
              Status1 = so1.Name, 
              WeekOfDate2 = (th2.WeekEndingDate == null) ? PayPeriod : th2.WeekEndingDate, 
              HoursWorked2 = (th2.TotalHoursWorked == null) ? 0 : th2.TotalHoursWorked, 
              Status2 = (string.IsNullOrEmpty(th2Final.Name)) ? "New" : th2Final.Name, 
              PTO = e.PTORemaining 
             }).ToList(); 

       return Json(TimeOverviewData, JsonRequestBehavior.AllowGet); 
      } 
     } 
     catch (Exception ex) 
     { 
      Response.StatusCode = (int)HttpStatusCode.BadRequest; 
      return Json(new { responseText = "Error getting data, please try again later" }, JsonRequestBehavior.AllowGet); 
     } 
    } 

    public static DateTime GetCurrentPayPeriod() 
    { 
     var KnownPayPeriodDate = DateTime.Parse("2007-11-10"); 
     while (KnownPayPeriodDate.CompareTo(DateTime.Today) < 0) 
     { 
      KnownPayPeriodDate = KnownPayPeriodDate.AddDays(14); 
     } 

     return ((KnownPayPeriodDate - DateTime.Today).Days < 7) ? KnownPayPeriodDate : KnownPayPeriodDate.AddDays(-14); 
    } 

    public static int GetEmployeeID(string adUserName) 
    { 
     adUserName = adUserName.Remove(0, 9); 

     using (var db = new JobSightDbContext()) 
     { 
      return db.Employees.Where(employee => employee.ADUserName == adUserName).Select(employee => employee.ID).First(); 
     } 
    } 

public class DashboardTimeOverviewVM 
{ 
    public int EmployeeID { get; set; } 
    public string Employee { get; set; } 
    public DateTime WeekOfDate1 { get; set; } 
    public decimal HoursWorked1 { get; set; } 
    public string Status1 { get; set; } 
    public DateTime WeekOfDate2 { get; set; } 
    public decimal HoursWorked2 { get; set; } 
    public string Status2 { get; set; } 
    public decimal PTO { get; set; } 
} 

public class TimeCardHeader 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 

    public int EmployeeID { get; set; } 
    public DateTime WeekEndingDate { get; set; } 
    public decimal TotalHoursWorked { get; set; } 
    public int CurrentStatusID { get; set; } 
    public decimal OtherPay { get; set; } 
    public int? ApprovedByID { get; set; } 
    public DateTime? DateSubmitted { get; set; } 
    public DateTime? DateApproved { get; set; } 

    [Column(TypeName = "varchar(MAX)")] 
    public string ManagerNotes { get; set; } 

    [ForeignKey("EmployeeID")] 
    public Employee Employee { get; set; } 

    [ForeignKey("ApprovedByID")] 
    public Employee ApprovedBy { get; set; } 

    [ForeignKey("CurrentStatusID")] 
    public StatusOption CurrentStatus { get; set; } 
} 

public class Employee 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 

    [Required] 
    public string FirstName { get; set; } 

    [Required] 
    public string LastName { get; set; } 

    [Required] 
    public string ADUserName { get; set; } 

    [Required] 
    public string Email { get; set; } 

    public int? ManagerID { get; set; } 

    [Required] 
    public string EmploymentType { get; set; } 

    [Required] 
    public string PhoneNumber { get; set; } 

    [Required] 
    public string OfficeLocation { get; set; } 

    public string MobilePhoneNumber { get; set; } 
    public decimal PTORemaining { get; set; } 
    public decimal PTOAccrualRate { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime? EndDate { get; set; } 
    public int ADPFileNumber { get; set; } 
    public int AirCardLateCheckinCount { get; set; } 
    public int VehicleLateCheckinCount { get; set; } 
    public int WexCardDriverID { get; set; } 
    public int? UpdatedByEmployeeID { get; set; } 
    public DateTime? DateUpdated { get; set; } 

    [ForeignKey("ManagerID")] 
    public Employee Manager { get; set; } 

    [ForeignKey("UpdatedByEmployeeID")] 
    public Employee UpdatedBy { get; set; } 
} 

public class StatusOption 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 

    [Required] 
    public string Name { get; set; } 
} 
+3

一開始,'(th2.TotalHoursWorked = = 0)? 0:th2.TotalHoursWorked'只是'th2.TotalHoursWorked'。現在,如果這是你想檢查無效的那個 - 你有沒有確定它在你的班級中被聲明爲「decimal?」?您沒有向我們展示'th2.TotalHoursWorked'或'DashboardTimeOverviewVM.HoursWorked2'的類型。如果你提供[mcve],那真的會有所幫助,所以我們可以忽略不相關的部分並查看相關部分。 –

回答

2

由於您​​變量從一個left outer join和相應的字段來是非空類型(如在你的情況decimal),最簡單的(和正確的)的方法是在​​執行null檢查:

HoursWorked2 = th2 == null ? 0 : th2.TotalHoursWorked 

僅與LINQ工程實體(和將產生LINQ NullReferenceException到對象)的另一種方法是使用流延到空類型:

HoursWorked2 = (decimal?)th2.TotalHoursWorked ?? 0 
+0

謝謝,甚至沒有想到只檢查'th2'爲null。我做了這個更新,現在一切都按預期顯示了 – Matthew

+0

這意味着只有當'TotalHoursWorked'可以爲空時,由於'Left Outer Join'導致'th2'爲空,否則是一個值類型,它永遠不會爲空 –

+0

@ MrinalKamboj正確。它類似於C#elvis操作符如何改變表達式的類型 - 「th2.TotalHoursWorked' - >'decimal','th2?.TotalHoursWorked' - >'decimal?' –

1

十進制是value type,所以它不能是Null

您的選擇:

  1. 重新定義TotalHoursWorked作爲decimal? - Nullable value type,那麼你就可以比較null

  2. 否則,請00.0M,以便它可以與在運行時間decimal類型,否則你有integer

比較
+1

親愛的羽絨選民,請出示裸露的最低禮貌來解釋您的行爲 –