我想扩展我的 IQueryable 以获取字段名列表,并且只将这些列返回到动态集合中。本质上,我想通过传入的字段/列名称来实现“选择”。该方法看起来像这样:
private IQueryable<TEnity> SetSelect(IQueryable<TEntity> query, List<string> fieldnames)
{
//Build up the Expression here
query = query.Select(expressionHere);
return query;
}
所以如果我正在查询像这样的对象:
public Class Dog
{
int Id{get;set;}
string Name{get;set;}
string Color{get;set;}
DateTime Birthdate{get;set;}
}
但我只想获取姓名和出生日期我可以通过调用 SetSelect(query, new List<string>{"Name", "Birthdate"});
来扩展 IQueryable
并会返回:
[{"Fido", 01-01-2017}, {"Spot", 05-04-1972}]
有没有人做过类似的事情,可以帮助我构建那个表达式?
感谢任何澄清。
注意:这是一个 .Net Core 应用程序
最佳答案
您可以通过调用 DynamicSelectGenerator
从实体中选择来生成动态选择。
public static Func<T, T> DynamicSelectGenerator<T>( string fields )
{
// get Properties of the T
var fields = typeof(T).GetProperties().Select(propertyInfo => propertyInfo.Name).ToArray();
// input parameter "o"
var xParameter = Expression.Parameter(typeof(T), "o");
// new statement "new Data()"
var xNew = Expression.New(typeof(T));
// create initializers
var bindings = fields.Split( ',' ).Select(o => o.Trim())
.Select(o =>
{
// property "Field1"
var mi = typeof(T).GetProperty(o);
// original value "o.Field1"
var xOriginal = Expression.Property(xParameter, mi);
// set value "Field1 = o.Field1"
return Expression.Bind(mi, xOriginal);
}
);
// initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }"
var xInit = Expression.MemberInit(xNew, bindings);
// expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }"
var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter);
// compile to Func<Data, Data>
return lambda.Compile();
}
例如使用这段代码:
var result = dbContextInstancs.EntityClass.Select(DynamicSelectGenerator<EntityClass>("Name", "Birthdate"));
关于generics - 在 .NET Core 中使用字段名动态构建 IQueryable Select 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42820866/