axelheer / nein-linq

NeinLinq provides helpful extensions for using LINQ providers such as Entity Framework that support only a minor subset of .NET functions, reusing functions, rewriting queries, even making them null-safe, and building dynamic queries using translatable predicates and selectors.
MIT License
509 stars 21 forks source link

Allow to add type conversions to `DynamicExpression.Cache` (expose it publicly?) #46

Open Shaddix opened 1 month ago

Shaddix commented 1 month ago

I'm using NeinLinq Dynamic query filtering / sorting with MongoDB. Everything's ok for strings/ints/etc, but there are issues if I try to filter by properties of BsonValue type:

System.ArgumentException
Argument types do not match
   at System.Linq.Expressions.Expression.Constant(Object value, Type type)
   at NeinLinq.DynamicExpression.CreateConstant(ParameterExpression target, Expression selector, String value, IFormatProvider provider)
   at NeinLinq.DynamicExpression.CreateComparison(ParameterExpression target, String selector, DynamicCompare comparer, String value, IFormatProvider provider)
   at NeinLinq.DynamicQueryable.Where[T](IQueryable`1 query, String selector, DynamicCompare comparer, String value, IFormatProvider provider)

It happens, because DynamicExpression.CreateConverter is unable to convert string to BsonValue (it looks for BsonValue.Parse method which doesn't exist).

But actually if I add the type converter manually (by pushing it to static DynamicExpression.Cache via reflection), it works great. Here's the converter for the reference:

        Func<Type, Func<string, IFormatProvider?, object>> converterFactory = (Type type) =>
        {
            return (value, formatProvider) => BsonValue.Create(value);
        };

So, if this DynamicExpression.Cache is publicly exposed (or there is some other way to inject type converters), that would be really great, since the dirty reflection that I have now wouldn't be needed

axelheer commented 1 month ago

see #47