mirror of
https://github.com/Biarity/Sieve.git
synced 2024-11-24 14:33:01 +01:00
Merge pull request #26 from zolrath/Compare-Nullable
Allow comparing Nullable via Expression.Constant
This commit is contained in:
commit
4fea535586
@ -142,7 +142,7 @@ namespace Sieve.Services
|
|||||||
? converter.ConvertFrom(filterTerm.Value)
|
? converter.ConvertFrom(filterTerm.Value)
|
||||||
: Convert.ChangeType(filterTerm.Value, property.PropertyType);
|
: Convert.ChangeType(filterTerm.Value, property.PropertyType);
|
||||||
|
|
||||||
Expression filterValue = GetClosureOverConstant(constantVal);
|
Expression filterValue = GetClosureOverConstant(constantVal, property.PropertyType);
|
||||||
|
|
||||||
dynamic propertyValue = Expression.PropertyOrField(parameterExpression, property.Name);
|
dynamic propertyValue = Expression.PropertyOrField(parameterExpression, property.Name);
|
||||||
|
|
||||||
@ -219,12 +219,13 @@ namespace Sieve.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Workaround to ensure that the filter value gets passed as a parameter in generated SQL from EF Core
|
// Workaround to ensure that the filter value gets passed as a parameter in generated SQL from EF Core
|
||||||
//See https://github.com/aspnet/EntityFrameworkCore/issues/3361
|
// See https://github.com/aspnet/EntityFrameworkCore/issues/3361
|
||||||
private Expression GetClosureOverConstant<T>(T constant)
|
// Expression.Constant passed the target type to allow Nullable comparison
|
||||||
|
// See http://bradwilson.typepad.com/blog/2008/07/creating-nullab.html
|
||||||
|
private Expression GetClosureOverConstant<T>(T constant, Type targetType)
|
||||||
{
|
{
|
||||||
Expression<Func<T>> closure = () => constant;
|
return Expression.Constant(constant, targetType);
|
||||||
return closure.Body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IQueryable<TEntity> ApplySorting<TEntity>(
|
private IQueryable<TEntity> ApplySorting<TEntity>(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Sieve.Attributes;
|
using Sieve.Attributes;
|
||||||
|
|
||||||
@ -14,6 +14,7 @@ namespace SieveTests.Entities
|
|||||||
[Sieve(CanFilter = true, CanSort = true)]
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
public int LikeCount { get; set; } = new Random().Next(0, 1000);
|
public int LikeCount { get; set; } = new Random().Next(0, 1000);
|
||||||
|
|
||||||
|
|
||||||
[Sieve(CanFilter = true, CanSort = true)]
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
public int CommentCount { get; set; } = new Random().Next(0, 1000);
|
public int CommentCount { get; set; } = new Random().Next(0, 1000);
|
||||||
|
|
||||||
@ -23,5 +24,8 @@ namespace SieveTests.Entities
|
|||||||
[Sieve(CanFilter = true, CanSort = true)]
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
[Column(TypeName = "datetime")]
|
[Column(TypeName = "datetime")]
|
||||||
public DateTime DateLastViewed { get; set; } = DateTime.UtcNow;
|
public DateTime DateLastViewed { get; set; } = DateTime.UtcNow;
|
||||||
|
|
||||||
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
|
public int? CategoryId { get; set; } = new Random().Next(0, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ namespace SieveTests.Migrations
|
|||||||
CommentCount = table.Column<int>(nullable: false),
|
CommentCount = table.Column<int>(nullable: false),
|
||||||
DateCreated = table.Column<DateTimeOffset>(nullable: false),
|
DateCreated = table.Column<DateTimeOffset>(nullable: false),
|
||||||
LikeCount = table.Column<int>(nullable: false),
|
LikeCount = table.Column<int>(nullable: false),
|
||||||
Title = table.Column<string>(nullable: true)
|
Title = table.Column<string>(nullable: true),
|
||||||
|
CategoryId = table.Column<int>(nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table => table.PrimaryKey("PK_Posts", x => x.Id));
|
constraints: table => table.PrimaryKey("PK_Posts", x => x.Id));
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ namespace SieveTests.Migrations
|
|||||||
|
|
||||||
b.Property<int>("LikeCount");
|
b.Property<int>("LikeCount");
|
||||||
|
|
||||||
|
b.Property<int?>("CategoryId");
|
||||||
|
|
||||||
b.Property<string>("Title");
|
b.Property<string>("Title");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
@ -19,6 +19,9 @@ namespace SieveUnitTests.Entities
|
|||||||
[Sieve(CanFilter = true, CanSort = true)]
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;
|
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
|
public int? CategoryId { get; set; } = new Random().Next(0, 4);
|
||||||
|
|
||||||
[Sieve(CanFilter = true, CanSort = true)]
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
public bool IsDraft { get; set; }
|
public bool IsDraft { get; set; }
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
@ -28,24 +28,28 @@ namespace SieveUnitTests
|
|||||||
Id = 0,
|
Id = 0,
|
||||||
Title = "A",
|
Title = "A",
|
||||||
LikeCount = 100,
|
LikeCount = 100,
|
||||||
IsDraft = true
|
IsDraft = true,
|
||||||
|
CategoryId = null,
|
||||||
},
|
},
|
||||||
new Post() {
|
new Post() {
|
||||||
Id = 1,
|
Id = 1,
|
||||||
Title = "B",
|
Title = "B",
|
||||||
LikeCount = 50,
|
LikeCount = 50,
|
||||||
IsDraft = false
|
IsDraft = false,
|
||||||
|
CategoryId = 1,
|
||||||
},
|
},
|
||||||
new Post() {
|
new Post() {
|
||||||
Id = 2,
|
Id = 2,
|
||||||
Title = "C",
|
Title = "C",
|
||||||
LikeCount = 0
|
LikeCount = 0,
|
||||||
|
CategoryId = 1,
|
||||||
},
|
},
|
||||||
new Post() {
|
new Post() {
|
||||||
Id = 3,
|
Id = 3,
|
||||||
Title = "D",
|
Title = "D",
|
||||||
LikeCount = 3,
|
LikeCount = 3,
|
||||||
IsDraft = true
|
IsDraft = true,
|
||||||
|
CategoryId = 2,
|
||||||
},
|
},
|
||||||
}.AsQueryable();
|
}.AsQueryable();
|
||||||
}
|
}
|
||||||
@ -103,6 +107,19 @@ namespace SieveUnitTests
|
|||||||
Assert.AreEqual(result.First().Id, 0);
|
Assert.AreEqual(result.First().Id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CanFilterNullableInts()
|
||||||
|
{
|
||||||
|
var model = new SieveModel()
|
||||||
|
{
|
||||||
|
Filters = "CategoryId==1"
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = _processor.Apply(model, _posts);
|
||||||
|
|
||||||
|
Assert.IsTrue(result.Count() == 2);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void EqualsDoesntFailWithNonStringTypes()
|
public void EqualsDoesntFailWithNonStringTypes()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user