C# 打开Datareader可防止POCO被填充

C# 打开Datareader可防止POCO被填充,c#,mysql,entity-framework,C#,Mysql,Entity Framework,我正试图用对我的数据库的查询结果填充POCO。resultset有多行,所以我只是对每个结果进行迭代,并用数据填充POCO,我得到了这个错误:“已经有一个打开的DataReader与这个连接关联,必须先关闭它。” 我在哪里搞砸了 事情是这样的: [Controller.cs] /// <summary> /// Populates the inner Ads list /// </summary> publi

我正试图用对我的数据库的查询结果填充POCO。resultset有多行,所以我只是对每个结果进行迭代,并用数据填充POCO,我得到了这个错误:“已经有一个打开的DataReader与这个连接关联,必须先关闭它。”

我在哪里搞砸了

事情是这样的:

[Controller.cs]

        /// <summary>
        /// Populates the inner Ads list
        /// </summary>
        public void FetchAds()
        {
            _ads = new List<Ad>();
            using (var context = (ApartmentDataEntities) DbContextFactory.GetInstance().GetDbContext<ApartmentDataEntities>())
            {
                foreach (var config in context.Configurations)
                {
                    _ads.Add(new AdModel(_basePath, config));
                }

            }

            AdsReady.SafeTrigger(this, new AdArray { Ads = _ads.ToArray() });
        }
//
///填充内部广告列表
/// 
公共广告
{
_ads=新列表();
使用(var context=(ApartmentDataEntities)DbContextFactory.GetInstance().GetDbContext())
{
foreach(context.Configurations中的var config)
{
_ads.Add(新的AdModel(_basePath,config));
}
}
SafeTrigger(这是新的AdArray{Ads=\u Ads.ToArray()});
}
[AdModel.cs](从POCO继承)

public AdModel(字符串baseFolder,配置单元)
{
_baseFolder=baseFolder;
格塔德(公寓);
}
/// 
///从数据库中填充广告
/// 
私有void GetAd(配置单元)
{
PropertyId=公寓.Property.id;
PropertyName=公寓.Property.name;
PropertyPhone=公寓.Property.phone;
PropertyAddress=公寓.Property.address;
AreaName=公寓.Property.MapArea.AreaName;
RegionName=公寓.Property.MapArea.Region.name;
PropertyZipCode=公寓.Property.zipCode;
佣金率=公寓.Property.佣金率;
Images=partment.Property.Images.Select(img=>img.id.ToArray();
YearBuild=公寓.Property.YearBuild;
功能=公寓.Property.Features;
Ammenities=公寓.Property.Ammenities;
CommunitySpecial=公寓.Property.CommunitySpecial;
PetPolicy=plant.Property.PetPolicy;
大小=公寓。大小;
浴室=公寓。浴室;
卧室=公寓。卧室;
价格=公寓价格;
PropertyImages=plant.Property.Images.Select(img=>img.imageContents.ToArray();
FloorplanImage=null;
Floorplan=null;
var configFloorplan=plant.Images.SingleOrDefault();
if(configFloorplan==null)返回;
FloorplanImage=configFloorplan.imageContents;
Floorplan=configFloorplan.id;
}

您正在使用EntityFramework吗?可能是因为GetAdd中的.Select是延迟加载的,因此在外部查询仍然打开时尝试查询数据库。尝试在context.Configurations之后添加toArray()。似乎我不得不到处散布这些,以避免出现错误。

通常最好是在查询本身中投影到另一个模型。像

_ads = (from apartment in context.Configurations
        let configFloorplan = apartment.Images.SingleOrDefault()
        select new AdModel
        {
            PropertyId = apartment.Property.id,
            PropertyName = apartment.Property.name,
            PropertyPhone = apartment.Property.phone,
            ...
            PropertyImages = apartment.Property.Images
                                      .Select(img => img.imageContents),
            FloorplanImage = configFloorplan.imageContents,
            Floorplan = configFloorplan.id
        }).ToList();
这确保了所有内容都作为一个查询执行。您的方法的问题是,当EF读取
context.Configurations
时,会执行其他查询来填充模型的其他属性


这可以通过在连接字符串中启用多个活动结果集(MARS)来解决(可能)。但这并不能解决这样一个事实,即您将执行大量的查询(每个具体化模型两个查询)。

我正在尝试这样做,并且(出于我自己的学术目的)对MVC(这是一个桌面应用程序,但我想强迫自己正确地做事情)同样严格(出于我自己的学术目的)。不管怎样,我想知道在查询中对另一个模型的投影将如何影响关注点的分离,因为我的控制器正在给模型提供要处理的数据(现在我写的数据听起来是错误的)。
_ads = (from apartment in context.Configurations
        let configFloorplan = apartment.Images.SingleOrDefault()
        select new AdModel
        {
            PropertyId = apartment.Property.id,
            PropertyName = apartment.Property.name,
            PropertyPhone = apartment.Property.phone,
            ...
            PropertyImages = apartment.Property.Images
                                      .Select(img => img.imageContents),
            FloorplanImage = configFloorplan.imageContents,
            Floorplan = configFloorplan.id
        }).ToList();