已经有一个与此Connection关联的开放DataReader必须先关闭+ asp.net mvc

nie*_*lsv 7 mysql sql asp.net asp.net-mvc entity-framework

我有一个表MySQL数据库的entites与它的多个领域,如ENTITY_TITLE,entity_description,....在表中还有3个外键user_id,region_idcategory_id.

在我的索引视图中,我想显示表中的所有实体(显示标题,描述,...,用户名,区域名称和类别名称).

这是我在我的控制器中所做的:

public ActionResult Index()
{
    var model = this.UnitOfWork.EntityRepository.Get();
    return View(model);
}
Run Code Online (Sandbox Code Playgroud)

在我的存储库中,我这样做:

public virtual IEnumerable<TEntity> Get(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    string includeProperties = "")
{
    IQueryable<TEntity> query = _dbSet;

    if (filter != null)
    {
        query = query.Where(filter);
    }

    foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
    {
        query = query.Include(includeProperty);
    }

    if (orderBy != null)
    {
        return orderBy(query).ToList();
    }
    else
    {
        return query.ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

我总是Input string was not in a correct format在最后一条规则(return query.ToList())上得到错误.

但是当我在规则之后检查_dbSet时IQueryable<TEntity> query = _dbSet;它已经给出了错误:There is already an open DataReader associated with this Connection which must be closed first.

这可能是因为我想从多个表中选择.但我该如何解决这个问题呢?我尝试MultipleActiveResultSets=True"像这样添加到我的ConnectionString:

<connectionStrings>
<add name="reuzzeCS" connectionString="server=localhost;uid=root;pwd=*****;Persist Security Info=True;database=reuzze;MultipleActiveResultSets=True"" providerName="MySql.Data.MySqlClient" />
Run Code Online (Sandbox Code Playgroud)

但这给了我关键字不存在的错误,因为我使用MySql.Data.MySqlClient ..

执行的查询是:

{SELECT Extent1.entity_id, Extent1.entity_title, Extent1.entity_description, Extent1.entity_starttime, Extent1.entity_endtime, Extent1.entity_instantsellingprice, Extent1.entity_shippingprice, Extent1.entity_condition, Extent1.entity_views, Extent1.entity_created, Extent1.entity_modified, Extent1.entity_deleted, Extent1.user_id, Extent1.region_id, Extent1.category_identitiesAS Extent1}

但是当他想要执行查询并且我想扩展结果时,我得到了错误 There is already an open DataReader associated with this Connection which must be closed first

编辑:
我的完整存储库:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace App.Data.orm.repositories
{
// REPO FROM TEACHER
public class GDMRepository<TEntity> where TEntity : class
{
    internal GDMContext _context;
    internal DbSet<TEntity> _dbSet;

    public GDMRepository(GDMContext context)
    {
        this._context = context;
        this._dbSet = _context.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = _dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

    public virtual TEntity GetByID(object id)
    {
        return _dbSet.Find(id);
    }

    public virtual void Insert(TEntity entity)
    {
        _dbSet.Add(entity);
    }

    public virtual void Delete(object id)
    {
        TEntity entityToDelete = _dbSet.Find(id);
        Delete(entityToDelete);
    }

    public virtual void Delete(TEntity entity)
    {
        if (_context.Entry(entity).State == EntityState.Detached)
        {
            _dbSet.Attach(entity);
        }
        _dbSet.Remove(entity);
    }

    public virtual void Update(TEntity entity)
    {
        _dbSet.Attach(entity);
        _context.Entry(entity).State = EntityState.Modified;
    }
}
}
Run Code Online (Sandbox Code Playgroud)

GDMContext类:

using App.Data.orm.mappings;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace App.Data.orm
{
public class GDMContext:DbContext
{
    public GDMContext() : base("reuzzeCS") { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //REMOVE STANDARD MAPPING IN ENTITY FRAMEWORK
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        //REGISTER MAPPERS
        modelBuilder.Configurations.Add(new UserMapping());
        modelBuilder.Configurations.Add(new PersonMapping());
        modelBuilder.Configurations.Add(new RoleMapping());

        modelBuilder.Configurations.Add(new EntityMapping());
        modelBuilder.Configurations.Add(new MediaMapping());
        modelBuilder.Configurations.Add(new BidMapping()); 
        modelBuilder.Configurations.Add(new CategoryMapping());
        modelBuilder.Configurations.Add(new AddressMapping());
        modelBuilder.Configurations.Add(new RegionMapping()); 
        modelBuilder.Configurations.Add(new MessageMapping());
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我的实体型号:

public class Entity
{
    public Int64 Id { get; set; }
    [Required(ErrorMessage = "Title is required")]
    [StringLength(255)]
    [DisplayName("Title")]
    public string Title { get; set; }
    [Required(ErrorMessage = "Description is required")]
    [DisplayName("Description")]
    public string Description { get; set; }
    [Required]
    public DateTime StartTime { get; set; }
    [Required]
    public DateTime EndTime { get; set; }
    /*[Required(ErrorMessage = "Type is required")]
    [StringLength(16)]
    [DisplayName("Type")]
    public string Type { get; set; }*/
    [Required]
    public decimal InstantSellingPrice { get; set; }
    public Nullable<decimal> ShippingPrice { get; set; }

    public Condition? Condition { get; set; }
    public Nullable<Int64> Views { get; set; }

    [Required]
    public DateTime CreateDate { get; set; }
    public Nullable<DateTime> ModifiedDate { get; set; }
    public Nullable<DateTime> DeletedDate { get; set; }

    public Int32 UserId { get; set; }

    public Int32 RegionId { get; set; }

    public Int16 CategoryId { get; set; }

    public virtual User User { get; set; }
    public virtual Region Region { get; set; }
    public virtual Category Category { get; set; }
    //public virtual ICollection<Category> Categories { get; set; }
    public virtual ICollection<User> Favorites { get; set; }
    public virtual ICollection<Bid> Bids { get; set; }
    public virtual ICollection<Media> Media { get; set; }
}

public enum Condition
{
    New = 1,
    Used = 2
}
Run Code Online (Sandbox Code Playgroud)

我的实体映射:

internal class EntityMapping : EntityTypeConfiguration<Entity>
{
    public EntityMapping()
        : base()
    {
        this.ToTable("entities", "reuzze");

        this.HasKey(t => t.Id);
        this.Property(t => t.Id).HasColumnName("entity_id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        this.Property(t => t.Title).HasColumnName("entity_title").IsRequired().HasMaxLength(255);
        this.Property(t => t.Description).HasColumnName("entity_description").IsRequired();
        this.Property(t => t.StartTime).HasColumnName("entity_starttime").IsRequired();
        this.Property(t => t.EndTime).HasColumnName("entity_endtime").IsRequired();
        //this.Property(t => t.Type).HasColumnName("entity_type").IsRequired();
        this.Property(t => t.InstantSellingPrice).HasColumnName("entity_instantsellingprice").IsRequired();
        this.Property(t => t.ShippingPrice).HasColumnName("entity_shippingprice").IsOptional();
        this.Property(t => t.Condition).HasColumnName("entity_condition").IsRequired();
        this.Property(t => t.Views).HasColumnName("entity_views").IsOptional();
        this.Property(t => t.CreateDate).HasColumnName("entity_created").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
        this.Property(t => t.ModifiedDate).HasColumnName("entity_modified").IsOptional();
        this.Property(t => t.DeletedDate).HasColumnName("entity_deleted").IsOptional();

        this.Property(t => t.UserId).HasColumnName("user_id").IsRequired();
        this.Property(t => t.RegionId).HasColumnName("region_id").IsRequired();
        this.Property(t => t.CategoryId).HasColumnName("category_id").IsRequired();

        //FOREIGN KEY MAPPINGS
        this.HasRequired(t => t.User).WithMany(p => p.Entities).HasForeignKey(f => f.UserId).WillCascadeOnDelete(false);
        this.HasRequired(t => t.Region).WithMany(p => p.Entities).HasForeignKey(f => f.RegionId);
        this.HasRequired(t => t.Category).WithMany(p => p.Entities).HasForeignKey(f => f.CategoryId);

        //MANY_TO_MANY MAPPINGS
        this.HasMany(t => t.Favorites)
            .WithMany(t => t.Favorites)
            .Map(mc =>
            {
                mc.ToTable("favorites");
                mc.MapLeftKey("entity_id");
                mc.MapRightKey("user_id");
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

链接到stacktrace图像!

更新:

  • 基地{SELECT Extent1.entity_id, Extent1.entity_title, Extent1.entity_description, Extent1.entity_starttime, Extent1.entity_endtime, Extent1.entity_instantsellingprice, Extent1.entity_shippingprice, Extent1.entity_condition, Extent1.entity_views, Extent1.entity_created, Extent1.entity_modified, Extent1.entity_deleted, Extent1.user_id, Extent1.region_id, Extent1.category_id FROM entitiesAS Extent1} System.Data.Entity.Internal.Linq.InternalQuery {System.Data.Entity.Internal.Linq.InternalSet}

Ram*_*ran 4

你的问题是

我认为 MySql 连接器可能不支持多个活动结果集,因此连接字符串中的设置对您没有帮助。

所以请尝试这种方式而不是你的代码

编辑 :

query.Include("User").Include("Region").Include("Category").ToList(); 
Run Code Online (Sandbox Code Playgroud)

如果您在更改后遇到同样的错误,请告诉我。

更新:

我已经为您更改了一些内容请使用此代码而不是您的方法

 public virtual IEnumerable<TEntity> Get(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    string includeProperties = "")
        {
            IQueryable<TEntity> query = _dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }


            if (orderBy != null)
            {
                return orderBy(query.Include("User").Include("Region").Include("Category").ToList()).ToList();
            }
            else
            {
                return query.Include("User").Include("Region").Include("Category").ToList(); 
            }
        }
Run Code Online (Sandbox Code Playgroud)

更新2:

这不是关于关闭连接。EF 正确管理连接。我对这个问题的理解是,在单个连接(或具有多个选择的单个命令)上执行多个数据检索命令,而在第一个 DataReader 完成读取之前执行下一个 DataReader。避免该异常的唯一方法是允许多个嵌套 DataReaders = 打开 MultipleActiveResultSets。经常发生这种情况的另一种情况是,当您迭代查询结果(IQueryable)时,您将在迭代内触发已加载实体的延迟加载。

堆栈溢出有很多人得到了你的问题的解决方案

1:实体框架:已经有一个与此命令关联的打开的DataReader

2:如何避免“已经有一个与此连接关联的打开的DataReader,必须首先关闭它”。在 MySql/net 连接器中?

3:错误:已经有一个与此命令关联的打开的 DataReader,必须先将其关闭

我个人的建议是,我认为你不要花更多的时间来解决这个错误,因为浪费时间和精力,你可以通过使用手动查询来完成。所以请尝试不同的方法。

您不需要拆分和格式化查询来避免input string was not correct format错误

你可以这样做而不是 return query.ToList();

return _dbSet.Users
    .Include(x => x.Region)
    .Include(x => x.Category).ToList();
Run Code Online (Sandbox Code Playgroud)

我认为您可以使用我上面的SO链接来做到这一点。

我的主要问题是:

实体框架可以支持ORM概念,那么为什么不尝试这种方式呢?你可以改变使用 ORM Concept 的想法。或许可以解决这个问题。 这是一个链接,请参阅本教程


归档时间:

查看次数:

17073 次

最近记录:

11 年,10 月 前