Open Cubody opened 1 year ago
System.ArgumentException: Method 'Boolean Contains(System.String)' declared on type 'System.String' cannot be called with instance of type 'ItPos.DataAccess.Common.Models.User.Institute' at System.Linq.Expressions.Expression.ValidateCallInstanceType(Type instanceType, MethodInfo method) at System.Linq.Expressions.Expression.ValidateStaticOrInstanceMethod(Expression instance, MethodInfo method) at System.Linq.Expressions.Expression.ValidateMethodAndGetParameters(Expression instance, MethodInfo method) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments) at AutoFilterer.Attributes.StringFilterOptionsAttribute.BuildExpressionWithoutComparison(StringFilterOption option, Expression expressionBody, PropertyInfo property, Object value) at AutoFilterer.Attributes.StringFilterOptionsAttribute.BuildExpression(Expression expressionBody, PropertyInfo targetProperty, PropertyInfo filterProperty, Object value) at AutoFilterer.Attributes.CompareToAttribute.BuildExpressionForProperty(Expression expressionBody, PropertyInfo targetProperty, PropertyInfo filterProperty, Object value) at AutoFilterer.Types.FilterBase.BuildExpression(Type entityType, Expression body)
Institute is a different type than string, so string
and Institute
can't be compared. You should compare Search parameter to one of the Institute parameter.
Something like"Institute.Name"
should be working:
public class StudentInfoShortResponseFilter : PaginationFilterBase
{
[CompareTo(nameof(StudentInfoShortResponse.FullName),
nameof(StudentInfoShortResponse.AcademicGroup),
nameof(StudentInfoShortResponse.StudentIdCard),
"Institute.Name")]
[StringFilterOptions(StringFilterOption.Contains)]
[ToLowerContainsComparison]
public string? Search { get; set; }
}
Oh, sorry, I missed that Institute is an enum.
Enums are numeric fields and stored as numeric value types in databases by default. If you want to compare strings to enums, you should project enum values as string value in a different field and filter that field with autofilterer. That projection might be done with Select()
LINQ method.
myDataSource.Select(x => new MyProjectedResult
{
FullName = x.FullName,
AcademicGroup = x. AcademicGroup,
StudentIdCard = x. StudentIdCard,
InstituteName = x.Institute?.ToString()
}).ApplyFilter(...)
And you can use InstituteName string field for filtering:
Institute is a different type than string, so string
and Institute
can't be compared. You should compare Search parameter to one of the Institute parameter.
Something like"Institute.Name"
should be working:
public class StudentInfoShortResponseFilter : PaginationFilterBase
{
[CompareTo(nameof(StudentInfoShortResponse.FullName),
nameof(StudentInfoShortResponse.AcademicGroup),
nameof(StudentInfoShortResponse.StudentIdCard),
"InstituteName")] // 👈 here
[StringFilterOptions(StringFilterOption.Contains)]
[ToLowerContainsComparison]
public string? Search { get; set; }
}
It says then that it can not do query with toString(), like not supported, but I'm using mapster, so Idk.
Thanks for the your answer btw! It's possible via straight property in Filter like
public Institute? Institute {get;set;}
But not via CompareToAttribute - it's strange thing. But I see why it works like it works.
When you see that a separate field is working, there is a feeling that the complex variable will also work. I would consider this as a possible vector for improving your solution. If I have the time/opportunity, I will take a look and try to come up with a solution.
I have such filter:
And when I'm trying to write in 'search' anything - it always gives me all records, not filtering it. StudentInfoShortResponse.Institute - enum type. If I'll delete this from attribute - it will search for other properties.
With such enum property in filter attribute it stops write filter in query.
If I'll write
in filter - all will be fine too.