我有一个要执行IQueryable
的{{1}}。在该选择中,我创建一个对象的新实例并运行一个函数,该函数将对象的值从IQueryable(b)复制到新创建的对象(新DTO),然后返回该实例。
IQueryable。选择:
Select
DTO中的功能
businessLayer.GetAll().Select( b => new DTO().InitInhertedProperties(b)).ToList();
复制功能
public DTO InitInhertedProperties(Base baseInstance)
{
return Utilities.InitInhertedProperties(this, baseInstance);
}
第一次将public static T InitInhertedProperties<T,K>(T instance, K baseClassInstance) where T : K
{
foreach (PropertyInfo propertyInfo in baseClassInstance.GetType().GetProperties())
{
object value = propertyInfo.GetValue(baseClassInstance, null);
if (null != value) propertyInfo.SetValue(instance, value, null);
}
return instance;
}
方法称为InitInhertedProperties
是一个空对象时,instance
具有应具有的值:
如您所见:一切工作都应该在第一次迭代中完成。现在是第二次迭代。
第二次baseClassInstance
方法被称为InitInhertedProperties
并不是一个新实例,而是第一次迭代中的一个。 insatnce
就是应该的样子:
这仅在使用baseClassInstance
时发生。使用IQueryable.Select
时,结果看起来与预期的一样。
这意味着可以解决此问题。但这只是解决方案,而不是解决方案。
List.Select
答案 0 :(得分:2)
在使用IQueryable
时,您必须绑定表达式。实体框架将检查您放入Select
,OrderBy
和其他方法中的每个表达式,并尝试将其转换为SQL。因此,您无法在lambda中调用仅由EF知道的任意方法
如果您想做某事,而SQL引擎没有直接支持,您可以致电AsEnumerable
:
businessLayer.GetAll().AsEnumerable().Select( ...
(请注意,AsEnumerable
比ToList
好,因为它保持惰性)
可能(取决于查询提供程序的版本)可能起作用的另一个选项是手动构建表达式:
public static Expression<Func<TEntity, TDto>> InitInhertedProperties<TEntity, TDto>() where TDto : TEntity
{
var entity = Expression.Parameter(typeof(BusinessObject), "b");
var newDto = Expression.New(typeof(Dto).GetConstructors().First());
var body = Expression.MemberInit(newDto,
typeof(TDto).GetProperties()
.Select(p => Expression.Bind(p, Expression.Property(entity, p.Name)))
);
return Expression.Lambda<Func<TEntity, TDto>>(body, entity);
}
用法:
var myExp = InitInhertedProperties<BusinessObject, Dto>();
var result = businessLayer.GetAll().Select(myExp).ToList();