C# 为什么IQueryable.Select对每个迭代使用相同的引用
我有一个C# 为什么IQueryable.Select对每个迭代使用相同的引用,c#,entity-framework,linq,.net-core,iqueryable,C#,Entity Framework,Linq,.net Core,Iqueryable,我有一个IQueryable,我想在其上执行选择。在该选择中,我创建一个对象的新实例,并运行一个函数,该函数将对象的值从IQueryable(b)复制到新创建的对象(新DTO),然后返回该实例 IQueryable。选择: businessLayer.GetAll().Select( b => new DTO().InitInhertedProperties(b)).ToList(); DTO中的函数: public DTO InitInhertedProperties(Base bas
IQueryable
,我想在其上执行选择。在该选择中,我创建一个对象的新实例,并运行一个函数,该函数将对象的值从IQueryable(b)复制到新创建的对象(新DTO),然后返回该实例
IQueryable。选择:
businessLayer.GetAll().Select( b => new DTO().InitInhertedProperties(b)).ToList();
DTO中的函数:
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;
}
使用IQueryable
时,您将绑定到表达式。实体框架将检查放入选择、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);
}
public静态表达式InitInhertedProperties(),其中TDto:tenty
{
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)))
);
返回表达式.Lambda(body,entity);
}
用法:
var myExp = InitInhertedProperties<BusinessObject, Dto>();
var result = businessLayer.GetAll().Select(myExp).ToList();
var myExp=InitInhertedProperties();
var result=businessLayer.GetAll().Select(myExp.ToList();
使用IQueryable
时,您将绑定到表达式。实体框架将检查放入选择、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);
}
public静态表达式InitInhertedProperties(),其中TDto:tenty
{
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)))
);
返回表达式.Lambda(body,entity);
}
用法:
var myExp = InitInhertedProperties<BusinessObject, Dto>();
var result = businessLayer.GetAll().Select(myExp).ToList();
var myExp=InitInhertedProperties();
var result=businessLayer.GetAll().Select(myExp.ToList();
我认为您的问题不在您发布的代码中。。。businessLayer.GetAll()在做什么?返回一个IQueryable?来自EF还是?是的,它确实从EF返回IQueryable!执行此操作:businessLayer.GetAll().ToList().Select(b=>newdto().InitInhertedProperties(b)).ToList();修正了错误。。但这只是一个解决方法,而不是解决方案。那么这对我来说是一个不清楚的部分,因为如果此方法为未执行的“Linq to Entities”-查询返回IQueryable,那么实际上应该会得到一个NotSupportedException异常。。。因为InitInhertedProperties在LINQtoEntities中是未知的。我认为您的问题不在您发布的代码中。。。businessLayer.GetAll()在做什么?返回一个IQueryable?来自EF还是?是的,它确实从EF返回IQueryable!执行此操作:businessLayer.GetAll().ToList().Select(b=>newdto().InitInhertedProperties(b)).ToList();修正了错误。。但这只是一个解决方法,而不是解决方案。那么这对我来说是一个不清楚的部分,因为如果此方法为未执行的“Linq to Entities”-查询返回IQueryable,那么实际上应该会得到一个NotSupportedException异常。。。因为InitInhertedProperties在Linq中对实体是未知的。