Modifying the DataSourceRequest Object to Map ViewModel Objects to EF Core Entities and Support Filtering and Sorting
Environment
Product Version | 2023.1.117 |
Product | DataSource for ASP.NET Core |
Description
I want to use Model Mapping, but my view model object and entities returned by Entity Framework are not identical. Thus, when I follow the Model mapping documentation I get an exception.
I have an EF Core entity:
public class Product
{
public long ID {get;set;}
public string Product_Name {get;set;}
}
And a corresponding ViewModel:
public class ProductVM
{
public long Id {get;set;}
public string ProductName {get;set;}
}
Solution
A possible approach to resolve the issue is to implement model mapping and map the different model properties to support filtering and sorting. The solution below is suggested by Dave, a member of our forums, and shows how to map model properties so filtering and sorting can be used:
public static class DataSourceRequestExtensions
{
public static void RemapMember(this DataSourceRequest request, string memberName, string newMemberName)
{
foreach (var sort in request.Sorts)
{
if (sort.Member.Equals(memberName))
{
sort.Member = newMemberName;
}
}
foreach (var filter in request.Filters)
{
if (filter is CompositeFilterDescriptor compositeFilterDescriptor)
{
foreach (var compositeFilter in compositeFilterDescriptor.FilterDescriptors)
{
RemapFilterDescription(compositeFilter, memberName, newMemberName);
}
}
RemapFilterDescription(filter, memberName, newMemberName);
}
}
private static void RemapFilterDescription(IFilterDescriptor filter, string memberName, string newMemberName)
{
if (!(filter is FilterDescriptor descriptor)) return;
if (descriptor.Member.Equals(memberName))
{
descriptor.Member = newMemberName;
}
}
}
Use the extension method to map the model properties so filtering and sorting works as expected:
public ActionResult Grid_Read([DataSourceRequest] DataSourceRequest request)
{
var data = myProductsService.GetAllProducts();
request.RemapMember("Id", "ID");
request.RemapMember("ProductName", "Product_Name");
var dsResult = data.ToDataSourceResult(request, model => new ProductVM()
{
Id = model.ID,
ProductName = model.Product_Name
});
return Json(dsResult);
}