简体   繁体   中英

NullReferenceException with Nullable DateTime despite null check

GetTodayItemCount() attempts to get today's item count using CreatedDtt in the Items model. Because CreatedDtt is a Nullable Datetime ( DateTime? ), I use a ternary operator within the Where 's lambda expression to make sure I am not trying to access the date of a null value later on in my equality comparison.

However, I still get the classic NullReferenceException? Object reference not set to an instance of an object NullReferenceException? Object reference not set to an instance of an object error, and I can confirm that row.CreatedDtt.Value.Date is where the issue is at.

  public Int64 GetTodayItemCount()
        {
            OrmLiteConnectionFactory dbFactory = new OrmLiteConnectionFactory(dbConn, SqlServerDialect.Provider);

            using (IDbConnection db = dbFactory.Open())
            {
                SqlExpression<Items> itemMatch = db.From<Items>()
                     .Where(row =>
                        (row.CreatedDtt.HasValue ?
                        row.CreatedDtt.Value.Date : DateTime.MinValue) == DateTime.Today
                      );

                Int64 itemCount = db.Count(itemMatch);
                db.Close();

                return itemCount;
            }
        }

How is row.CreatedDtt.Value.Date being accessed when I am checking for its valid value beforehand, and how can I accomplish the desired outcome of GetTodayItemCount() without getting a NullReferenceException error?

Since the solution doesn't seem to be as straightforward as I had predicted, I am adding the stack trace below in case there is any use in it:

   at ServiceStack.OrmLite.SqlExpression`1.GetQuotedColumnName(ModelDefinition tableDef, String memberName)
   at ServiceStack.OrmLite.SqlExpression`1.GetMemberExpression(MemberExpression m)
   at ServiceStack.OrmLite.SqlExpression`1.VisitMemberAccess(MemberExpression m)
   at ServiceStack.OrmLite.SqlExpression`1.Visit(Expression exp)
   at ServiceStack.OrmLite.SqlExpression`1.VisitBinary(BinaryExpression b)
   at ServiceStack.OrmLite.SqlExpression`1.Visit(Expression exp)
   at ServiceStack.OrmLite.SqlExpression`1.VisitBinary(BinaryExpression b)
   at ServiceStack.OrmLite.SqlExpression`1.Visit(Expression exp)
   at ServiceStack.OrmLite.SqlExpression`1.VisitLambda(LambdaExpression lambda)
   at ServiceStack.OrmLite.SqlExpression`1.Visit(Expression exp)
   at ServiceStack.OrmLite.SqlExpression`1.AppendToWhere(String condition, Expression predicate)
   at ServiceStack.OrmLite.SqlExpression`1.Where(Expression`1 predicate)
   at GroupRedemptionsScanner.DBHandlers.GetTodayItemCount() in [directory/file/line number etc]

You can't apply C# logic to RDBMS Server columns. If you want to test fuzzy precision data types like Dates you should use a range instead, eg:

.Where(row => row.CreatedDtt != null && 
              row.CreatedDtt >= DateTime.Now.Date && 
              row.CreatedDtt <  DateTime.Now.Date.AddDays(1)));

I tried to reproduce your error in every way you could imagine but I couldn't. The only way was explicitly leaving a row in null. But I don't know if it's a possible case. Anyway, I propose you to refactor it using Null Propagation. This way:

.Where(row => row?.CreatedDtt?.Date == DateTime.Today);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM