-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement request: Support Generics for FilteringOptionsBaseAttribute in Custom Expression for a Property #64
Comments
We can create some adapter packages for those libraries so they can be used with autofilterer without a pain |
thank you |
Keep this issue open until the development is completed for Generics support :) |
Hi @enisn , Thank you very much for your attention to this topic. I have an idea and I'm wondering if it's possible to implement it in your project? Let me first share my code snippet. Once you see it, you'll understand. I believe it's a way to save a lot of work and make the code more concise. I plan to do three fixed queries in advance, such as 1. all (unconditional), 2. query records created by me (CreateBy == UserId Of Login), and 3. query records created today (Created == Today) public class ProductsWithPaginationQuery : PaginationFilterBase, ICacheableRequest<PaginatedData<ProductDto>>
{
public string? Name { get; set; }
public string? Brand { get; set; }
public string? Unit { get; set; }
public Range<decimal> Price { get; set; } = new();
[CompareTo("Name", "Brand", "Description")] // <-- This filter will be applied to Name or Brand or Description.
[StringFilterOptions(StringFilterOption.Contains)]
public string? Keyword { get; set; }
[CompareTo(typeof(SearchProductsWithListView), "Name")]
public ProductListView ListView { get; set; } = ProductListView.All; //<-- When the user selects a different ListView,
// a custom query expression is executed on the backend.
// For example, if the user selects "My Products",
// the query will be x => x.CreatedBy == CurrentUser.UserId
public UserProfile? CurrentUser { get; set; } // <-- This CurrentUser property gets its value from the information of
// the currently logged in user
public override string ToString()
{
return $"CurrentUser:{CurrentUser?.UserId},ListView:{ListView},Search:{Keyword},Name:{Name},Brand:{Brand},Unit:{Unit},MinPrice:{Price?.Min},MaxPrice:{Price?.Max},Sort:{Sort},SortBy:{SortBy},{Page},{PerPage}";
}
public string CacheKey => ProductCacheKey.GetPaginationCacheKey($"{this}");
public MemoryCacheEntryOptions? Options => ProductCacheKey.MemoryCacheEntryOptions;
}
public enum ProductListView
{
[Description("All")]
All,
[Description("My Products")]
My,
[Description("Created Toady")]
CreatedToday,
}
public class SearchProductsWithListView : FilteringOptionsBaseAttribute
{
public override Expression BuildExpression(Expression expressionBody, PropertyInfo targetProperty, PropertyInfo filterProperty, object value)
{
var today = DateTime.Now.Date;
var start = Convert.ToDateTime(today.ToString("yyyy-MM-dd",CultureInfo.CurrentCulture) + " 00:00:00", CultureInfo.CurrentCulture);
var end = Convert.ToDateTime(today.ToString("yyyy-MM-dd",CultureInfo.CurrentCulture) + " 23:59:59", CultureInfo.CurrentCulture);
//var currentUser = filterProperty.CurrentUser;
var listview = (ProductListView)value;
return listview switch {
ProductListView.All => expressionBody,
//ProductListView.My=> Expression.Equal(Expression.Property(expressionBody, "CreatedBy"), Expression.Constant(currentUser?.UserId)),
ProductListView.CreatedToday => Expression.GreaterThanOrEqual(Expression.Property(expressionBody, "Created"),
Expression.Constant(start, typeof(DateTime?)))
.Combine(Expression.LessThanOrEqual(Expression.Property(expressionBody, "Created"),
Expression.Constant(end, typeof(DateTime?))),
CombineType.And),
_=> expressionBody
};
}
}
///// ProductListView.CreatedToday => Expression.GreaterThanOrEqual(Expression.Property(expressionBody, "Created"),
// Expression.Constant(start, typeof(DateTime?)))
// .Combine(Expression.LessThanOrEqual(Expression.Property(expressionBody, "Created"),
// Expression.Constant(end, typeof(DateTime?))),
// CombineType.And),
// this Expression is working. However, the code snippet I shared is not yet compiling. I need your help to implement this feature. Do you have any good ideas on how to achieve this? The problem I'm facing now is that I cannot get the property value of the current user of ProductsWithPaginationQuery in class SearchProductsWithListView : FilteringOptionsBaseAttribute{}, so I cannot build the query expression for the query "created by me". |
The following code is my own way to implement the query expression made by the ListView:
|
@enisn |
Hello @enisn, |
I have an idea related to the "Custom Expression for a Property" feature mentioned in your documentation. My idea is to make the FilteringOptionsBaseAttribute support generics, which would make writing LINQ expressions easier. Do you think this is possible?
For reference, here is another project that might be helpful:
https://github.com/ClaveConsulting/Expressionify
https://github.com/lukemcgregor/LinqExpander
Thank you for considering my suggestion.
The text was updated successfully, but these errors were encountered: