Question: Is it possible to do case-insensitive search
I would like to do case-insensitive search with startswith,endwith and Contains. Please let me know this is possible or not.
This is related to your SQL-server settings ?
@rajeshmuraleedharan When you install SQL Server you must specify the collation. CI is for case insensitive and AI is for accent insensitive. Anyway, It could be great to make requests in CI, AI, CS or AS "on demand".
I think, you should able to use: title.Contains("string", StringComparison.OrdinalIgnoreCase); if it works is a question of your linq adapter
@jogibear9988 This will not work for this library I think.
Sadly it doesn't work, the part "StringComparison" is treated as a property and you get an error saying, that the property or field 'StringComparison' exists in the currently used type. However, you can use the string value of the enum, described in the Enum Type Support Section.
users.Where("GivenName.Contains(\"sa\", \"OrdinalIgnoreCase\")");
Works perfectly for me :-)
How do you do a case sensitive search with this library ???
Query.Where($"{dataPropertie.Name}.ToString().Trim().ToLower().Contains(@0)", cols.Values.ToStringNullSafe().Trim().ToLower()).OrderBy(dataPropertie.Name).ToList();
I tried something like this but is not working
@rajeshmuraleedharan With #450, StringComparison is now supported, so the following should work:
users.Where("GivenName.Contains(\"sa\", StringComparison.OrdinalIgnoreCase)");
@wilari932 How would you write a case-insensitive search using standard expression trees? If this would work:
var cols1 = cols.Values?.ToString().Trim();
Query = Query.Where(x => x.Contains(cols1, StringComparison.OrdinalIgnoreCase));
then the following should also work:
var cols1 = cols.Values?.ToString().Trim();
Query = Query.Where("Contains(@0, StringComparison.OrdinalIgnoreCase)", cols1);
users.Where("GivenName.Contains("sa", StringComparison.OrdinalIgnoreCase)");
Still does not work for me in 1.2.6: No applicable method 'Contains' exists in type 'String'
@khmurach How are you escaping the quotation marks? Also, is this being run against a database or other Queryable provider?
@khmurach How are you escaping the quotation marks? Also, is this being run against a database or other Queryable provider?
Yes, I'm escaping. I'm using Where on List<User>().AsQueryable()
@khmurach This works for me:
var lst = new List<User>();
var qry = lst.AsQueryable().Where("GivenName.Contains(\"sa\", StringComparison.OrdinalIgnoreCase)");
public class User {
public string? GivenName { get; set; }
}
Visualizing qry.Expression:
Which framework are you targeting?
@zspitz I have generic method so there is no properties to use in standard Where(x=>x.Name.Contains("value")).
IQueryable<T> ApplyFilter(IQueryable<T> dataAll, object filter)
This line works fine:
dataQueryable = dataQueryable.Where("{0}.ToLower().Contains(@0)".FormatWith(item.Key), item.Value.ToString().ToLower());
But I would like to get rid of ToLower()
@khmurach This works for me:
var lst = new List<User>(); var qry = lst.AsQueryable().Where("GivenName.Contains(\"sa\", StringComparison.OrdinalIgnoreCase)"); public class User { public string? GivenName { get; set; } }Visualizing
qry.Expression:Which framework are you targeting?
targetFramework="net451"
@khmurach It seems that .NET Framework 4.5.1 doesn't support this overload of Contains:
How would you do this with a strongly-typed query?
N.B. The filter you are passing into ApplyFilter could also be generic:
IQueryable<T> ApplyFilter(IQueryable<T> dataAll, Func<T, bool> filter) {
}
and then you would have strong-typing on the filter itself. Although I don't quite see what it gives you over the standard .Where.
Even in this simplified example, first two queries works fine but the last one throws error:
var items = new List<ListItem>() { new ListItem { Title = "John" }, new ListItem { Title = "Adam" }, new ListItem { Title = "john" } };
// works fine
var result1 = items.AsQueryable().Where("Title.ToLower().Contains(\"jo\")").ToList();
// works fine
var result2 = items.AsQueryable().Where(x => x.Title.Contains("jo", StringComparison.OrdinalIgnoreCase)).ToList();
// throws exception
var result3 = items.AsQueryable().Where("Title.Contains(\"jo\", StringComparison.OrdinalIgnoreCase)").ToList();
I'm using
object filter
in
IQueryable<T> ApplyFilter(IQueryable<T> dataAll, object filter)
to be able to use any object (projection) as a filter and to use reflection to scan props and values and apply them as a filter to List<T>:
var usersCache = _repository.GetAll<User>();
var filter1 = new User{ FirstName = "jo", LastName = "wes" };
var filter2 = new UserQuery{ FirstName = "jo" };
var result1 = ApplyFilter(usersCache, filter1);
var result2 = ApplyFilter(usersCache, filter2);
Any updates on how to do an case invariant search?
I'm also having this problem with Contains with the System.Linq.Dynamic.Core package at version 1.2.18, but only when running my actual code. If I run Unit tests everything works perfectly.
[Fact]
public void DynamicLinq_SingleContains_SimpleText_CaseInsensitiveOverload()
{
var filter = "(Name != null && Name.Contains(\"Blu\", StringComparison.CurrentCultureIgnoreCase))";
var data = GetDynamicLinqTestData().AsQueryable();
var filteredData = data.Where(filter).ToArray();
Assert.Single(filteredData);
}
[Fact]
public void DynamicLinq_SingleContains_ReplacementText_CaseInsensitiveOverload()
{
var filter = "(Name != null && Name.Contains(@0, StringComparison.CurrentCultureIgnoreCase))";
var filterParams = new List<object>();
filterParams.Add("Blu");
var data = GetDynamicLinqTestData().AsQueryable();
var filteredData = data.Where(filter, filterParams.ToArray()).ToArray();
Assert.Single(filteredData);
}
Both of these tests work fine in XUnit. But when I run my code that creates the exact same thing (either way, and I have unit tests on those create functions too) I get System.Linq.Dynamic.Core.Exceptions.ParseException No applicable method 'Contains' exists in type 'String'
I've tried also using the older method of doing just an escaped string of the enum like "CurrentCultureIgnoreCase" but that doesn't work either. Doesn't matter which enum I use, OrdinalIgnoreCase doesn't work either. It does appear to work if I let it be case sensitive, but that's not ideal.
I just don't understand why it works in unit tests and not in practice.
I will also note that string.StartsWith and EndsWith both DO work in unit tests and in practice using the case sensitive enums. Which is even weirder.
Update:
- Nevermind, I forgot the Unit Test Project is using .Net 5.0 and the actual project is using Framework 4.8 where that String.Contains overload doesn't exist apparently. Yay old code making things hard.
Closing..