diff --git a/src/Filter.cs b/src/Filter.cs index a711ba1..8d3bc7f 100644 --- a/src/Filter.cs +++ b/src/Filter.cs @@ -37,6 +37,12 @@ public class Filter [DataMember(Name = "logic")] public string Logic { get; set; } + /// <summary> + /// Gets or sets the filtering logic. Can be set to "or" or "and". Set to null unless Filters is set. + /// </summary> + [DataMember(Name = "ignoreCase")] + public bool IgnoreCase { get; set; } + /// <summary> /// Gets or sets the child filter expressions. Set to null if there are no child expressions. /// </summary> @@ -144,7 +150,7 @@ public string ToExpression(Type type, IList<Filter> filters) if (Operator == "doesnotcontain") { - return String.Format("{0} != null && !{0}.{1}(@{2})", Field, comparison, index); + return String.Format(!IgnoreCase ? "{0} != null && !{0}.{1}(@{2})" : "{0} != null && !{0}.ToLower().{1}(@{2}.ToLower())", Field, comparison, index); } if (Operator == "isnull" || Operator == "isnotnull") @@ -164,7 +170,7 @@ public string ToExpression(Type type, IList<Filter> filters) if (comparison == "StartsWith" || comparison == "EndsWith" || comparison == "Contains") { - return String.Format("{0} != null && {0}.{1}(@{2})", Field, comparison, index); + return String.Format(!IgnoreCase ? "{0} != null && {0}.{1}(@{2})" : "{0} != null && {0}.ToLower().{1}(@{2}.ToLower())", Field, comparison, index); } return String.Format("{0} {1} @{2}", Field, comparison, index); diff --git a/test/Kendo.DynamicLinqCore.Tests/Data/MockContext.cs b/test/Kendo.DynamicLinqCore.Tests/Data/MockContext.cs index d3092db..e456069 100644 --- a/test/Kendo.DynamicLinqCore.Tests/Data/MockContext.cs +++ b/test/Kendo.DynamicLinqCore.Tests/Data/MockContext.cs @@ -15,7 +15,7 @@ public class MockContext : DbContext public static MockContext GetDefaultInMemoryDbContext() { - if(_defaultDbContext != null) return _defaultDbContext; + if (_defaultDbContext != null) return _defaultDbContext; var serviceProvider = new ServiceCollection().AddDbContext<MockContext>(options => options.UseLazyLoadingProxies().UseInMemoryDatabase("Kendo")).BuildServiceProvider(); @@ -34,7 +34,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { // Add employee data modelBuilder.Entity<Employee>().HasData( - new Employee { + new Employee + { Number = 1, Name = "Monie", Identification = Guid.Parse("ff5f9bb3-f805-4f52-a5f9-fbd0493d5b8f"), @@ -42,10 +43,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) Weight = 48.5, Salary = 1000, Gender = Gender.F, - Birthday = new DateTime(2000,5,5), + Birthday = new DateTime(2000, 5, 5), CompanyId = Guid.Parse("c2cbfe28-f82a-4904-8075-bf98729d434f") }, - new Employee { + new Employee + { Number = 2, Identification = Guid.Parse("a3ee172c-fdf3-4390-9bb1-d5a70ccfbb3b"), Name = "CoCo", @@ -53,20 +55,22 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) Salary = 2500, Weight = 69.2, Gender = Gender.M, - Birthday = new DateTime(1986,10,10), + Birthday = new DateTime(1986, 10, 9, 16, 0, 0), CompanyId = Guid.Parse("c2cbfe28-f82a-4904-8075-bf98729d434f") }, - new Employee { + new Employee + { Number = 3, Identification = Guid.Parse("aad8a5ec-9b5a-4c5f-9d3b-d7a39df6392f"), Name = "Kirin", Introduce = "I'm Kirin", Weight = 73.8, Gender = Gender.M, - Birthday = new DateTime(1984,7,8), + Birthday = new DateTime(1984, 7, 8), CompanyId = Guid.Parse("5dd641dd-2ba4-4dfd-9572-81325ecd8940") }, - new Employee { + new Employee + { Number = 4, Identification = Guid.Parse("a4e918a9-46f9-4a13-8f37-e8771bf7dc5c"), Name = "Rock", @@ -74,10 +78,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) Salary = 1750, Weight = 82.1, Gender = Gender.M, - Birthday = new DateTime(1976,11,6), + Birthday = new DateTime(1976, 11, 5, 16, 0, 0), CompanyId = Guid.Parse("80a6570c-ca98-4661-adde-e4d5a8637ee5") }, - new Employee { + new Employee + { Number = 5, Identification = Guid.Parse("3e5f4514-1a3f-402a-8e97-a2fa95ccb91b"), Name = "Pikachu", @@ -85,10 +90,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) Salary = 6600, Weight = 52.9, Gender = Gender.P, - Birthday = new DateTime(2005,3,16), + Birthday = new DateTime(2005, 3, 16), CompanyId = Guid.Parse("80a6570c-ca98-4661-adde-e4d5a8637ee5") }, - new Employee { + new Employee + { Number = 6, Identification = Guid.Parse("0814bceb-3481-49c6-8dfb-0a398f2b55f3"), Name = "Zed", @@ -96,22 +102,25 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) Salary = 3000, Weight = 71.6, Gender = Gender.M, - Birthday = new DateTime(2003,1,22), + Birthday = new DateTime(2003, 1, 22), CompanyId = Guid.Parse("80a6570c-ca98-4661-adde-e4d5a8637ee5") } ); // Add company data modelBuilder.Entity<Company>().HasData( - new Company { + new Company + { Id = Guid.Parse("c2cbfe28-f82a-4904-8075-bf98729d434f"), Name = "Microsoft" }, - new Company { + new Company + { Id = Guid.Parse("5dd641dd-2ba4-4dfd-9572-81325ecd8940"), Name = "Google" }, - new Company { + new Company + { Id = Guid.Parse("80a6570c-ca98-4661-adde-e4d5a8637ee5"), Name = "Apple" } diff --git a/test/Kendo.DynamicLinqCore.Tests/FilterTest.cs b/test/Kendo.DynamicLinqCore.Tests/FilterTest.cs index 5f7c64c..ffd8db5 100644 --- a/test/Kendo.DynamicLinqCore.Tests/FilterTest.cs +++ b/test/Kendo.DynamicLinqCore.Tests/FilterTest.cs @@ -17,9 +17,9 @@ public class FilterTest { private MockContext _dbContext; - #if NETCOREAPP3_1 +#if NETCOREAPP3_1 private JsonSerializerOptions jsonSerializerOptions = CustomJsonSerializerOptions.DefaultOptions; - #endif +#endif [SetUp] public void Setup() @@ -30,8 +30,9 @@ public void Setup() [Test] public void InputParameter_SubPropertyContains_CheckResultCount() { - var result = _dbContext.Employee.Include(x=>x.Company).AsQueryable().ToDataSourceResult(10, 0, null, new Filter { - Field ="Company.Name", + var result = _dbContext.Employee.Include(x => x.Company).AsQueryable().ToDataSourceResult(10, 0, null, new Filter + { + Field = "Company.Name", Value = "Microsoft", Operator = "contains", Logic = "and" @@ -39,8 +40,9 @@ public void InputParameter_SubPropertyContains_CheckResultCount() Assert.AreEqual(2, result.Total); - var result2 = _dbContext.Employee.AsQueryable().ToDataSourceResult(10, 0, null, new Filter { - Filters = new [] + var result2 = _dbContext.Employee.AsQueryable().ToDataSourceResult(10, 0, null, new Filter + { + Filters = new[] { new Filter { @@ -55,16 +57,48 @@ public void InputParameter_SubPropertyContains_CheckResultCount() Assert.AreEqual(2, result2.Total); } + [Test] + public void InputParameter_SubPropertyContains_Case_Insensitive_CheckResultCount() + { + var result = _dbContext.Employee.Include(x => x.Company).AsQueryable().ToDataSourceResult(10, 0, null, new Filter + { + Field = "Company.Name", + Value = "microsoft", + Operator = "contains", + Logic = "and", + IgnoreCase = true, + }); + + Assert.AreEqual(2, result.Total); + + var result2 = _dbContext.Employee.AsQueryable().ToDataSourceResult(10, 0, null, new Filter + { + Filters = new[] + { + new Filter + { + Field ="Company.Name", + Operator = "contains", + Value = "microsoft", + IgnoreCase = true, + } + }, + Logic = "and" + }); + + Assert.AreEqual(2, result2.Total); + } + [Test] public void InputDataSourceRequest_DecimalGreaterAndLess_CheckResultCount() { // source string = {"take":20,"skip":0,"filter":{"logic":"and","filters":[{"field":"Salary","operator":"gt","value":999.00},{"field":"Salary","operator":"lt","value":6000.00}]}} - #if NETCOREAPP3_1 +#if NETCOREAPP3_1 var request = JsonSerializer.Deserialize<DataSourceRequest>("{\"take\":20,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"field\":\"Salary\",\"operator\":\"gt\",\"value\":999.00},{\"field\":\"Salary\",\"operator\":\"lt\",\"value\":6000.00}]}}", jsonSerializerOptions); - #else - var request = JsonConvert.DeserializeObject<DataSourceRequest>("{\"take\":20,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"field\":\"Salary\",\"operator\":\"gt\",\"value\":999.00},{\"field\":\"Salary\",\"operator\":\"lt\",\"value\":6000.00}]}}"); - #endif +#else + var request = JsonConvert.DeserializeObject<DataSourceRequest>("{\"take\":20,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"field\":\"Salary\",\"operator\":\"gt\",\"value\":999.00},{\"field\":\"Salary\",\"operator\":\"lt\",\"value\":6000.00}]}}"); +#endif var result = _dbContext.Employee.AsQueryable().ToDataSourceResult(request); Assert.AreEqual(4, result.Total); @@ -75,11 +109,11 @@ public void InputDataSourceRequest_DoubleGreaterAndLessEqual_CheckResultCount() { // source string = {"take":20,"skip":0,"filter":{"logic":"and","filters":[{"field":"Weight","operator":"gt","value":48},{"field":"Weight","operator":"lt","value":69.2}]}} - #if NETCOREAPP3_1 +#if NETCOREAPP3_1 var request = JsonSerializer.Deserialize<DataSourceRequest>("{\"take\":20,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"field\":\"Weight\",\"operator\":\"gt\",\"value\":48},{\"field\":\"Weight\",\"operator\":\"lte\",\"value\":69.2}]}}", jsonSerializerOptions); - #else - var request = JsonConvert.DeserializeObject<DataSourceRequest>("{\"take\":20,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"field\":\"Weight\",\"operator\":\"gt\",\"value\":48},{\"field\":\"Weight\",\"operator\":\"lte\",\"value\":69.2}]}}"); - #endif +#else + var request = JsonConvert.DeserializeObject<DataSourceRequest>("{\"take\":20,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"field\":\"Weight\",\"operator\":\"gt\",\"value\":48},{\"field\":\"Weight\",\"operator\":\"lte\",\"value\":69.2}]}}"); +#endif var result = _dbContext.Employee.AsQueryable().ToDataSourceResult(request); Assert.AreEqual(3, result.Total); @@ -90,11 +124,11 @@ public void InputDataSourceRequest_ManyConditions_CheckResultCount() { // source string = {\"take\":10,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"logic\":\"or\",\"filters\":[{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1986-10-09T16:00:00.000Z\"},{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1976-11-05T16:00:00.000Z\"}]},{\"logic\":\"and\",\"filters\":[{\"field\":\"Salary\",\"operator\":\"gte\",\"value\":1000},{\"field\":\"Salary\",\"operator\":\"lte\",\"value\":6000}]}]}} - #if NETCOREAPP3_1 +#if NETCOREAPP3_1 var request = JsonSerializer.Deserialize<DataSourceRequest>("{\"take\":10,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"logic\":\"or\",\"filters\":[{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1986-10-09T16:00:00.000Z\"},{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1976-11-05T16:00:00.000Z\"}]},{\"logic\":\"and\",\"filters\":[{\"field\":\"Salary\",\"operator\":\"gte\",\"value\":1000},{\"field\":\"Salary\",\"operator\":\"lte\",\"value\":6000}]}]}}", jsonSerializerOptions); - #else - var request = JsonConvert.DeserializeObject<DataSourceRequest>("{\"take\":10,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"logic\":\"or\",\"filters\":[{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1986-10-09T16:00:00.000Z\"},{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1976-11-05T16:00:00.000Z\"}]},{\"logic\":\"and\",\"filters\":[{\"field\":\"Salary\",\"operator\":\"gte\",\"value\":1000},{\"field\":\"Salary\",\"operator\":\"lte\",\"value\":6000}]}]}}"); - #endif +#else + var request = JsonConvert.DeserializeObject<DataSourceRequest>("{\"take\":10,\"skip\":0,\"filter\":{\"logic\":\"and\",\"filters\":[{\"logic\":\"or\",\"filters\":[{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1986-10-09T16:00:00.000Z\"},{\"field\":\"Birthday\",\"operator\":\"eq\",\"value\":\"1976-11-05T16:00:00.000Z\"}]},{\"logic\":\"and\",\"filters\":[{\"field\":\"Salary\",\"operator\":\"gte\",\"value\":1000},{\"field\":\"Salary\",\"operator\":\"lte\",\"value\":6000}]}]}}"); +#endif var result = _dbContext.Employee.AsQueryable().ToDataSourceResult(request); Assert.AreEqual(2, result.Total);