From dcea5b4f45b2ee0cf33fe300d241e31fadbf8248 Mon Sep 17 00:00:00 2001 From: George Seeger Date: Wed, 3 Jan 2018 09:07:19 +0000 Subject: [PATCH] Fix for null reference exception on datetime.utcnow.date in where clauses --- .../Engine/DML/WhereClauseWriterTests.cs | 21 ++++++++++++++ Dashing/Engine/DML/WhereClauseWriter.cs | 28 +++++++++++-------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/Dashing.Tests/Engine/DML/WhereClauseWriterTests.cs b/Dashing.Tests/Engine/DML/WhereClauseWriterTests.cs index ad7f921d..80d5e616 100644 --- a/Dashing.Tests/Engine/DML/WhereClauseWriterTests.cs +++ b/Dashing.Tests/Engine/DML/WhereClauseWriterTests.cs @@ -768,6 +768,27 @@ public void WhereContainsNullableCheck() { Assert.Equal(" where ((t_100.[Nullable] is not null) and t_100.[Name] like @l_1)", actual.Sql); } + [Fact] + public void DateTimedotNowAsItStands() { + var target = MakeTarget(); + Expression> pred = c => c.CommentDate <= DateTime.UtcNow; + var now = DateTime.UtcNow; + var actual = target.GenerateSql(new[] { pred }, null); + var param = (DateTime)actual.Parameters.GetValue("l_1"); + Assert.Equal(" where ([CommentDate] <= @l_1)", actual.Sql); + Assert.True(Math.Abs((param - now).TotalSeconds) < 60); //if it's within a minute, it's just the execution times + } + + [Fact] + public void DateTimedotDateFix() { + var target = MakeTarget(); + Expression> pred = c => c.CommentDate <= DateTime.UtcNow.Date; + var actual = target.GenerateSql(new[] { pred }, null); + var param = (DateTime)actual.Parameters.GetValue("l_1"); + Assert.Equal(" where ([CommentDate] <= @l_1)", actual.Sql); + Assert.True(DateTime.UtcNow.Date <= param && param <= DateTime.UtcNow.Date); + } + private static WhereClauseWriter MakeTarget() { return new WhereClauseWriter(new SqlServerDialect(), MakeConfig()); } diff --git a/Dashing/Engine/DML/WhereClauseWriter.cs b/Dashing/Engine/DML/WhereClauseWriter.cs index c7e653b6..5e777759 100644 --- a/Dashing/Engine/DML/WhereClauseWriter.cs +++ b/Dashing/Engine/DML/WhereClauseWriter.cs @@ -351,23 +351,27 @@ private ISqlElement VisitMethodCall(MethodCallExpression exp) { } private ISqlElement VisitMemberAccess(MemberExpression exp) { - if (exp.Expression == null) { - // static property - if (this.isTopOfBinaryOrMethod) { - // quicker path - var propInfo = exp.Member as PropertyInfo; - if (propInfo != null) { - return this.AddParameter(propInfo.GetValue(null)); - } - var fieldInfo = exp.Member as FieldInfo; + if (exp.Expression == null) { // static property + + //quick path + var propInfo = exp.Member as PropertyInfo; + if (propInfo != null) { + this.value = propInfo.GetValue(null); + } else { + var fieldInfo = exp.Member as FieldInfo; if (fieldInfo != null) { - return this.AddParameter(fieldInfo.GetValue(null)); + this.value = fieldInfo.GetValue(null); + } else { + // slow path + this.value = this.GetDynamicValue(exp); } + } - // slow path - return this.AddParameter(this.GetDynamicValue(exp)); + if (this.isTopOfBinaryOrMethod) { + return this.AddParameter(this.value); } + this.isConstantExpression = true; return null; }