Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么IQueryable.Select对每个迭代使用相同的引用_C#_Entity Framework_Linq_.net Core_Iqueryable - Fatal编程技术网

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中对实体是未知的。