我有查询
return this._articlesRepository.GetEntities()
.Join(this._categoryRepository.GetEntities(),
article => article.CategoryId,
cat => cat.Id, (article, cat) => new {article, CategoryName = cat.Title}).Select(new T());
我有select的可查询扩展名。我尝试为动态生成的选择查询创建扩展。
public static IQueryable<TResult> Select<TSource, TResult>(this IQueryable<TSource> source, TResult result)
{
var resultType = typeof(TResult);
var resultObj = Expression.New(resultType);
var receiverProperties = resultType.GetProperties();
Type type = typeof(TSource);
ParameterExpression sourceParameter = Expression.Parameter(type, "item");
ParameterExpression anyParameter = null;
var resultParameters = new List<MemberBinding>();
foreach (var receiverProperty in receiverProperties)
{
var sourceProperty = typeof(TSource).GetProperty(receiverProperty.Name);
if (sourceProperty != null)
{
var sourcePropertyAccess = Expression.MakeMemberAccess(sourceParameter, sourceProperty);
var memberInit = Expression.Bind(receiverProperty, sourcePropertyAccess);
resultParameters.Add(memberInit);
}
}
if (typeof(TSource).Name.Contains("AnonymousType"))
{
foreach (var property in typeof(TSource).GetProperties())
{
if (property.PropertyType.BaseType == typeof(BaseEntity))
{
anyParameter = Expression.Parameter(property.PropertyType, "item."+property.Name);
foreach (var receiverProperty in receiverProperties)
{
var sourceProperty = property.PropertyType.GetProperty(receiverProperty.Name);
if (sourceProperty != null)
{
var sourcePropertyAccess = Expression.MakeMemberAccess(anyParameter, sourceProperty);
var memberInit = Expression.Bind(receiverProperty, sourcePropertyAccess);
resultParameters.Add(memberInit);
}
}
}
}
}
if (anyParameter != null)
{
var selector = Expression.Lambda<Func<TSource, TResult>>(Expression.MemberInit(resultObj, resultParameters), sourceParameter, anyParameter);
var method = Expression.Call(typeof(Queryable), "Select", new[] { source.ElementType, selector.Body.Type }, source.Expression, Expression.Quote(selector));
return source.Provider.CreateQuery<TResult>(method);
}
else
{
var selector = Expression.Lambda<Func<TSource, TResult>>(Expression.MemberInit(resultObj, resultParameters), sourceParameter);
var method = Expression.Call(typeof(Queryable), "Select", new[] { source.ElementType, selector.Body.Type }, source.Expression, Expression.Quote(selector));
return source.Provider.CreateQuery<TResult>(method);
}
}
但是我的代码在这一刻落下了
var selector
= Expression.Lambda<Func<TSource, TResult>>
(Expression.MemberInit(resultObj, resultParameters),
sourceParameter,
anyParameter);
我无法理解为什么?我明白我的代码看起来很糟糕。但后来我解决了这个问题。
我的旧代码工作正常
public static IQueryable<TResult> Select<TSource, TResult>(this IQueryable<TSource> source, TResult result)
{
var resultType = typeof(TResult);
var resultObj = Expression.New(resultType);
var receiverProperties = resultType.GetProperties();
Type type = typeof(TSource);
ParameterExpression sourceParameter = Expression.Parameter(type, "item");
var resultParameters = new List<MemberBinding>();
foreach (var receiverProperty in receiverProperties)
{
var sourceProperty = typeof(TSource).GetProperty(receiverProperty.Name);
if (sourceProperty != null)
{
var sourcePropertyAccess = Expression.MakeMemberAccess(sourceParameter, sourceProperty);
var memberInit = Expression.Bind(receiverProperty, sourcePropertyAccess);
resultParameters.Add(memberInit);
}
}
var selector = Expression.Lambda<Func<TSource, TResult>>(Expression.MemberInit(resultObj, resultParameters), sourceParameter);
var method = Expression.Call(typeof(Queryable), "Select", new[] { source.ElementType, selector.Body.Type }, source.Expression, Expression.Quote(selector));
return source.Provider.CreateQuery<TResult>(method);
}