System.Linq.Dynamic.Core
System.Linq.Dynamic.Core copied to clipboard
Where(List.Any(Field in @0), params) causes ParseException: '')' or ',' expected'
1. Description
Expression "Where" seems to not working with params in this kind of case : Where(List.Any(Field in @0), params)
2. Exception
Exception message: System.Linq.Dynamic.Core.Exceptions.ParseException: '')' or ',' expected'
Stack trace: at System.Linq.Dynamic.Core.Tokenizer.TextParser.ValidateToken(TokenId t, String errorMessage)
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseArgumentList()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseEnumerable(Expression instance, Type elementType, String methodName, Int32 errorPos, Type type)
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseMemberAccess(Type type, Expression expression)
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParsePrimary()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseUnary()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseMultiplicative()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAdditive()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseShiftOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseComparisonOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLogicalAndOrOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
at System.Linq.Dynamic.Core.Parser.ExpressionParser.Parse(Type resultType, Boolean createParameterCtor)
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Type delegateType, ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, Type itType, Type resultType, String expression, Object[] values)
at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where(IQueryable source, ParsingConfig config, String predicate, Object[] args)
at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[TSource](IQueryable`1 source, ParsingConfig config, String predicate, Object[] args)
at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[TSource](IQueryable`1 source, String predicate, Object[] args)
at SecConfigModel.TDD.TDDDynamicLinqBug.GetEntityFilters_TestIn() in TDDDynamicLinqBug.cs:line 102
3. Fiddle or Project
Here is what I used to reproduce the bug : I have 2 classes : Organization and Site. An organization contains a list for sites. Site only contains a name. I wrote couple of way to access to the data, and at the end, the one which doesn't work.
[Fact]
public void GetEntityFilters_TestIn()
{
//public class Organization
//{
// public ICollection<Site> Sites { get; set; }
//}
//public class Site
//{
// public string Code { get; set; }
//}
//var organizations = new List<Organization>()
//{
// new()
// {
// Code = "OrganizationA",
// Sites = new List<Site>()
// {
// new()
// {
// Code = "SiteNorth1",
// },
// new() {
// Code = "SiteNorth2",
// }
// }
// },
// new()
// {
// Code = "OrganizationB",
// Sites = new List<Site>()
// {
// new()
// {
// Code = "SiteNorth3",
// },
// new() {
// Code = "SiteNorth4",
// }
// }
// },
// new()
// {
// Code = "OrganizationC",
// Sites = new List<Site>()
// {
// new()
// {
// Code = "SiteNorth1",
// },
// new() {
// Code = "SiteNorth5",
// }
// }
// }
//};
var siteFilters = new List<string>() { "SiteNorth1", "SiteNorth5" };
// Working by accessing directly code from sites
var test1 = _dbContext.Sites.Where("Code in @0", siteFilters);
// Working by accessing from organizations with predicate params for an equal expression
var test2 = _dbContext.Organizations.Where("Sites.Any(Code = @0)", siteFilters.First());
// Working by accessing from organizations with classic LINQ
var test3 = _dbContext.Organizations.Where(_ => _.Sites.Any(_ => siteFilters.Contains(_.Code)));
// Working by accessing from organizations with string predicate
var test5 = _dbContext.Organizations.Where("Sites.Any(Code in (\"SiteNorth1\", \"SiteNorth5\"))");
// Not working : error : System.Linq.Dynamic.Core.Exceptions.ParseException: '')' or ',' expected'
var test6 = _dbContext.Organizations.Where("Sites.Any(Code in @0)", siteFilters);
}
4. Any further technical details
If you need any information, I'll be glad to help ! Regards
When using your code and a simple Queryable, it works fine.
Please see this PR for details: https://github.com/zzzprojects/System.Linq.Dynamic.Core/pull/761