最近、同様の回答を見たと確信していますが、見つかりません...
エンティティのタイプと選択するプロパティのタイプがわかっている場合、これは非常に簡単です。
public IQueryable<TProperty> SelectProperty<TEntity, TProperty>(DbContext context, string propertyName)
where TEntity : class
{
var parameter = Expression.Parameter(typeof(TEntity));
var body = Expression.Property(parameter, propertyName);
var lambda = Expression.Lambda<Func<TEntity, TProperty>>(body, parameter);
var result = context.Set<TEntity>().Select (lambda).Distinct();
return result;
}
プロパティのタイプを予測できない場合、式の作成はより困難になります。
public IQueryable SelectProperty<TEntity>(DbContext context, string propertyName)
where TEntity : class
{
var entities = context.Set<TEntity>();
var query = entities.AsQueryable();
var parameter = Expression.Parameter(typeof(TEntity), "instance");
var propertyAccess = Expression.Property(parameter, propertyName);
var projection = Expression.Lambda(propertyAccess, parameter);
var selectExpression = Expression.Call(
typeof(Queryable).GetMethods()
.First (x => x.Name == "Select")
.MakeGenericMethod(new[]{ typeof(TEntity), propertyAccess.Type }),
query.Expression,
projection);
var distinctExpression = Expression.Call(
typeof(Queryable).GetMethods()
.First (x => x.Name == "Distinct")
.MakeGenericMethod(new[]{ propertyAccess.Type }),
selectExpression);
var result = query.Provider.CreateQuery(distinctExpression);
return result;
}