C# 动态LINQ滤波
如何使用不同于模型的字段创建动态搜索列表C# 动态LINQ滤波,c#,linq,C#,Linq,如何使用不同于模型的字段创建动态搜索列表 public class UserModel { public int UserId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string DisplayName { get {return $
public class UserModel
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string DisplayName
{
get {return $"{ LastName }, { FirstName }"; }
}
}
// Sample search
private void Search(string fieldname, string searchString)
{
List<UserModel> data = Users.Where(x => x.fieldname == searchString).ToList();
}
公共类用户模型
{
public int UserId{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串显示名
{
获取{return$“{LastName},{FirstName}”;}
}
}
//样本搜索
私有无效搜索(字符串字段名、字符串搜索字符串)
{
List data=Users.Where(x=>x.fieldname==searchString.ToList();
}
快速而肮脏的方法是使用带有预定义属性名称的开关。我不建议允许用户指定过滤依据的确切属性或列,因为这会带来隐私风险和安全漏洞(例如,允许用户通过电子邮件、姓名或密码搜索其他用户,而您没有意识到这一点)
这些扩展方法可以这样使用:
private async Task<List<UserModel>> SearchUsersAsync( UserProperty filterProp = UserProperty.None, String filterValue = null, UserProperty sortProp = UserProperty.None, Boolean sortAscending = true )
{
List<User> users = await this.Users
.WhereProperty( filterProp, filterValue )
.OrderByProperty( sortProp, sortAscending )
.ToListAsync()
.ConfigureAwait(false);
List<UserModel> userViewModels = users
.Select( u => UserModel.FromUserEntity( u ) )
.ToList();
return userViewModels;
}
private async任务SearchUsersAsync(UserProperty filterProp=UserProperty.None,String filterValue=null,UserProperty sortProp=UserProperty.None,Boolean sortAscending=true)
{
列表用户=等待此操作。用户
.WhereProperty(filterProp,filterValue)
.OrderByProperty(sortProp、sortAscending)
.ToListAsync()
.配置等待(错误);
List userViewModels=用户
.Select(u=>UserModel.FromUserEntity(u))
.ToList();
返回userViewModels;
}
您可以使用表达式参数:
using System.Linq.Expressions;
//...
private List<UserModel> Search<T>(Expression<Func<UserModel, T>> criteria)
{
return Users.Where(criteria).ToList();
}
我发现字典对于保存所有硬编码的内容非常有用:
private Dictionary<string, Func<UserModel, string, bool>> _filters =
new Dictionary<string, Func<UserModel, string, bool>>()
{
{ "FirstName", (u, x) => u.FirstName == x },
{ "LastName", (u, x) => u.LastName == x },
{ "DisplayName", (u, x) => u.DisplayName == x },
};
private void Search(string fieldname, string searchString)
{
List<UserModel> data = Users.Where(u => _filters[fieldname](u, searchString)).ToList();
}
private Dictionary\u过滤器=
新字典()
{
{“FirstName”,(u,x)=>u.FirstName==x},
{“LastName”,(u,x)=>u.LastName==x},
{“DisplayName”,(u,x)=>u.DisplayName==x},
};
私有无效搜索(字符串字段名、字符串搜索字符串)
{
列表数据=用户。其中(u=>_filters[fieldname](u,searchString)).ToList();
}
欢迎来到SO!请再多描述一下:)这些答案是解决我问题的完美办法。最详细的方法是在这里。@Enigmativity:如果动态搜索条件是基于外部用户数据(字符串)或代码库内部的动态数据(调用方希望使用不同的条件),则有点含糊不清。似乎是后者,尽管您的适用于前者。这不应该是私有静态只读IReadOnlyDictionary\u过滤器吗?@Dai-这取决于OP是否希望在运行时修改过滤器。
using System.Linq.Expressions;
//...
private List<UserModel> Search<T>(Expression<Func<UserModel, T>> criteria)
{
return Users.Where(criteria).ToList();
}
var matches = model.Search(x => x.FirstName == "Bob");
private Dictionary<string, Func<UserModel, string, bool>> _filters =
new Dictionary<string, Func<UserModel, string, bool>>()
{
{ "FirstName", (u, x) => u.FirstName == x },
{ "LastName", (u, x) => u.LastName == x },
{ "DisplayName", (u, x) => u.DisplayName == x },
};
private void Search(string fieldname, string searchString)
{
List<UserModel> data = Users.Where(u => _filters[fieldname](u, searchString)).ToList();
}