C# 将DbSet传递给参数类型为IEnumerable的方法时出现奇怪的EF行为<&燃气轮机;

C# 将DbSet传递给参数类型为IEnumerable的方法时出现奇怪的EF行为<&燃气轮机;,c#,entity-framework-4,C#,Entity Framework 4,我有一个repository类,它正在查询EF DbContext,如下所示: public IEnumerable<ProductFilterData> GetAllProducts() { return this.DataContext.Products.Select(x => new ProductFilterData { Id = x.Id, Name = x.Name, ProductDetailLevelCode = x.ProductDetailLevel.

我有一个repository类,它正在查询EF DbContext,如下所示:

public IEnumerable<ProductFilterData> GetAllProducts()
{
   return this.DataContext.Products.Select(x => new ProductFilterData { Id = x.Id, Name = x.Name, ProductDetailLevelCode = x.ProductDetailLevel.Code, Description = x.Description, ParentProductIds = x.ParentProducts.Select(p => p.Id) });
}
public IEnumerable GetAllProducts()
{
返回此.DataContext.Products.Select(x=>newproductFilterData{Id=x.Id,Name=x.Name,ProductDetailLevelCode=x.ProductDetailLevel.Code,Description=x.Description,parentProductId=x.ParentProducts.Select(p=>p.Id)});
}
这很好用。但是,当我将此代码重构为:

public IEnumerable<ProductFilterData> GetAllProducts()
{
    return this.MapToProductFilterData(this.DataContext.Products);
}

private IEnumerable<ProductFilterData> MapToProductFilterData(IEnumerable<Product> products)
{
    return products.Select(x => new ProductFilterData { Id = x.Id, Name = x.Name, ProductDetailLevelCode = x.ProductDetailLevel.Code, Description = x.Description, ParentProductIds = x.ParentProducts.Select(p => p.Id) });
}
public IEnumerable GetAllProducts()
{
返回此.MapToProductFilterData(this.DataContext.Products);
}
私有IEnumerable MapToProductFilterData(IEnumerable产品)
{
返回产品。选择(x=>new ProductFilterData{Id=x.Id,Name=x.Name,ProductDetailLevelCode=x.ProductDetailLevel.Code,Description=x.Description,ParentProductId=x.ParentProducts.Select(p=>p.Id)});
}
我得到一个例外:

已存在与此命令关联的打开的DataReader,该命令 必须先关闭


为什么将对DbSet的引用传递给方法会导致EF的行为发生变化?顺便说一句,如果我将MapToProductFilterData的参数类型更改为IQueryable,那么它可以工作。另外,如果我删除了关系映射,它也会起作用。

您必须将其更改为
IQueryable
,因为如果您将其作为
IEnumerable
传递,您实际上会执行查询
SELECT*FROM Product
。您的方法开始迭代结果集,但是您的投影调用了
x.ParentProducts.Select(p=>p.Id)
,这会导致延迟加载
ParentProducts
导航属性。延迟加载会打开第二个活动数据读取器,只有在您拥有它的情况下才可以使用。

您必须将其更改为
IQueryable
,因为如果您将其作为
IEnumerable
传递,您实际上会执行查询
SELECT*FROM Product
。您的方法开始迭代结果集,但是您的投影调用了
x.ParentProducts.Select(p=>p.Id)
,这会导致延迟加载
ParentProducts
导航属性。延迟加载将打开第二个活动数据读取器,只有在您拥有该读取器的情况下才可以使用。

谢谢。为了阐明您的观点,正在执行一个不同的Select扩展方法(IEnumerable而不是IQueryable),这会导致不同的行为。谢谢。为了阐明您的观点,正在执行不同的Select扩展方法(IEnumerable而不是IQueryable),这会导致不同的行为。