I have search method with gets as parameter some DTO and make where filtering dynamically by DTO properties. The problem I get when using reflection is that I should explicitly cast to a property type that I am using. Is there a way to make it dynamic too so that the method that that make filtering can work without knowing type of a property. I am using Dynamic Ling Library.
CODE:
public async Task<ServiceResponceWithData<List<SearchResponseDTO>>> SearchAsync(SearchDTO model)
{
var users = from user in _userManeger.Users
join ur in _context.UserRoles
on user.Id equals ur.UserId
select new SearchResponseDTO
{
UserName = user.UserName,
Email = user.Email,
PhoneNumber = user.PhoneNumber,
FirstName = user.FirstName,
LastName = user.LastName,
Roles = _roleManager.Roles
.Where(c => c.Id == ur.RoleId)
.Select(c => c.Name)
.ToList()
};
var startResult = users;
var props = typeof(SearchDTO).GetProperties();
foreach (var prop in props)
{
if(prop.Name != "Role")
{
users = FilterWithWhereByStringTypeProperty(users, prop, model);
}
else
{
if (model.Role != null)
{
var results = users.Where(c => c.Roles.Any(r => r == model.Role));
users = results.Any() ? results : users;
}
}
}
var endResultList = startResult == users ? new List<SearchResponseDTO>() :await users.ToListAsync();
return new ServiceResponceWithData<List<SearchResponseDTO>>() { Data = endResultList, Success = true };
}
private IQueryable<SearchResponseDTO> FilterWithWhereByStringTypeProperty(IQueryable<SearchResponseDTO> collection,
PropertyInfo property,SearchDTO model )
{
var propertyName = property.Name;
var modelPropVal = property.GetValue(model);
if (modelPropVal == null) return collection;
string val = (string)modelPropVal;
string condition = String.Format("{0} == \"{1}\"", propertyName, val);
var fillteredColl = collection.Where(condition);
return fillteredColl.Any() ? fillteredColl : collection;
}
}
You could use System.Linq.Dynamic.Core .
In that case your code could be like ( not tested ):
var users = from user in _userManeger.Users
join ur in _context.UserRoles on user.Id equals ur.UserId
select new SearchResponseDTO
{
UserName = user.UserName,
Email = user.Email,
PhoneNumber = user.PhoneNumber,
FirstName = user.FirstName,
LastName = user.LastName,
Roles = _roleManager.Roles
.Where(c => c.Id == ur.RoleId)
.Select(c => c.Name)
.ToList()
};
IQueryable query = users;
var props = typeof(SearchDTO).GetProperties();
foreach (var prop in props)
{
if (prop.Name != "Role")
{
query = query.Where($"{prop.Name} == @0", prop.GetValue(model, null));
}
else
{
if (model.Role != null)
{
query = users.Where(c => c.Roles.Any(r => r == model.Role));
}
}
}
return query.ToList();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.