在LINQ查询中检查NULL为十进制

时间:2016-09-28 18:23:33

标签: c# linq

在我的LINQ查询的赋值部分中,我需要检查值是否为null,如果是,则指定默认值。返回的值类型是十进制,当我与null比较时,我得到警告

  

表达式的结果总是“假”'因为'十进制'的类型值绝不等于' null'类型'十进制?'

如果我尝试比较它以查看值是否为0,那么我得到错误

  

转换为值类型' System.Decimal'失败,因为具体化值为null。结果类型的通用参数或查询必须使用可空类型。

检查HoursWorked2是否为null的最佳方法是什么,如果它为null,则为其分配默认值?

编辑:  我不认为所有的代码都是需要的,但是因为其他人认为这里需要的是与之相关的所有代码:

    // 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; }
}

2 个答案:

答案 0 :(得分:3)

由于您的th2变量来自left outer join并且相应的字段是非可空类型(例如您的decimal),因此最简单(也是正确)的方法就是执行对null进行th2检查:

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

另一种仅适用于LINQ to Entities(并将在LINQ to Objects中生成NullReferenceException)的方法是使用强制转换为可空类型:

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

答案 1 :(得分:1)

十进制是value type,因此它不能是Null

您的选择:

  1. TotalHoursWorked重新定义为decimal? - Nullable value type,然后您可以与null值进行比较

  2. 否则,将0设为0.0M,以便在运行时将其与decimal类型进行比较,否则您将与{{1}进行比较}值