C# 创建动态linq语句
我的应用程序中有一个模型如下所示:C# 创建动态linq语句,c#,linq,C#,Linq,我的应用程序中有一个模型如下所示: 公共类PersonViewModel { 公共Guid Id{get;set;} 公共字符串DisplayName{get;set;} 公共字符串名{get;set;} 公共字符串LastName{get;set;} 公共字符串Upn{get;set;} // ... } 目前,我正在使用此扩展方法进行选择: public static IQueryable SelectBasic(此IQueryable personViewModels) { 返回pers
公共类PersonViewModel
{
公共Guid Id{get;set;}
公共字符串DisplayName{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串Upn{get;set;}
// ...
}
目前,我正在使用此扩展方法进行选择:
public static IQueryable SelectBasic(此IQueryable personViewModels)
{
返回personViewModels。选择(p=>new PersonViewModel
{
Id=p.Id,
DisplayName=p.DisplayName,
Upn=p.Upn
});
}
//这个用起来像
dbContext.People.AsQueryable().SelectBasic();
//这将与dbContext.People.AsQueryable()相同;
我想将select语句转换为动态语句,如下所示。但我不知道如何创建Linq表达式来实现这一点
公共静态IQueryable SelectProperties(此IQueryable personViewModels,
string propertyNames=“Id,DisplayName,Upn”)
{
var properties=propertyNames.Split(',');
返回personViewModels。选择(p=>new PersonViewModel
{
//仅选择属性数组中的属性
});
}
//像
dbContext.People.AsQueryable().SelectProperties(“Id,Upn”);
我找到了System.Linq.Expressions
名称空间,但文档很难找到。我找不到任何关于它的样品。注意:我不想要匿名类型,因为这是dotnet core 3 web api将返回的内容
我正在尝试选择动态参数(用户指定)。我没有尝试使用动态过滤器。使用原始选择
personViewModels.Select(p =>
new PersonViewModel {
Id = p.Id,
DisplayName = p.DisplayName,
Upn = p.Upn
}
);
作为需要为所需表达式构建的表达式树的指南,请选择表达式
参考文献
请注意与以下代码关联的注释,以了解select表达式是如何动态构建的
public static IQueryable<PersonViewModel> SelectProperties(
this IQueryable<PersonViewModel> personViewModels,
string propertyNames = "Id,DisplayName,Upn") {
var properties = propertyNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var type = typeof(PersonViewModel);
// p =>
var parameter = Expression.Parameter(type, "p");
// create bindings for initialization
var bindings = properties
.Select(s => {
// property
var property = type.GetProperty(s);
// original value
var propertyExpression = Expression.Property(parameter, property);
// set value "Property = p.Property"
return Expression.Bind(property, propertyExpression);
}
);
// new PersonViewModel()
var newViewModel = Expression.New(type);
// new PersonViewModel { Property1 = p.Property1, ... }
var body = Expression.MemberInit(newViewModel, bindings);
// p => new PersonViewModel { Property1 = p.Property1, ... }
var selector = Expression.Lambda<Func<PersonViewModel, PersonViewModel>>(body, parameter);
return personViewModels.Select(selector);
}
公共静态IQueryable SelectProperties(
这个IQueryable personViewModels,
string propertyNames=“Id,DisplayName,Upn”){
var properties=propertyNames.Split(新字符[]{',},StringSplitOptions.RemoveEmptyEntries);
变量类型=类型(PersonViewModel);
//p=>
var参数=表达式参数(类型为“p”);
//为初始化创建绑定
var绑定=属性
。选择(s=>{
//财产
var property=type.GetProperty;
//原值
var propertyExpression=Expression.Property(参数,属性);
//设置值“Property=p.Property”
返回表达式Bind(property,propertyExpression);
}
);
//新PersonViewModel()
var newViewModel=Expression.New(类型);
//新PersonViewModel{Property1=p.Property1,…}
var body=Expression.MemberInit(newViewModel,绑定);
//p=>new PersonViewModel{Property1=p.Property1,…}
变量选择器=表达式.Lambda(主体,参数);
返回personViewModels。选择(选择器);
}
引用我甚至不理解你的代码。@MarcoSalerno我已经试着使示例代码更好。我的主要问题是为什么?我看不出您的扩展方法比普通的有任何优势。选择?我想字符串在运行时可能会更改?这就是你在这里想要实现的吗?@Liam这正是我想要实现的!您在示例代码中的注释非常有用。这就是我问题的解决办法!下面是代码的通用版本