簡體   English   中英

如何使用反射通過每個屬性動態查詢 IQueryable 數組?

[英]How to dynamically query IQueryable array by each property using reflection?

我有搜索方法,以獲取一些 DTO 作為參數,並通過 DTO 屬性動態過濾 where。 使用反射時遇到的問題是我應該顯式轉換為我正在使用的屬性類型。 有沒有辦法讓它也動態化,以便在不知道屬性類型的情況下進行過濾的方法可以工作。 我正在使用動態凌庫。

代碼:

 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;
    }
}

您可以使用System.Linq.Dynamic.Core

在這種情況下,您的代碼可能類似於(未測試):

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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM