我正在使用EF和Oracle数据库构建一个简单的ASP.NET API。当我想从数据库表中获取所有元素时,响应(500)说“该操作无法完成,因为已经处理了DbContext”。

 

好吧,在将其发布到这里之前,我已经尝试解决此问题。但是我不能。我的控制器代码如下。

 public class PruebasController : ApiController
 {

    //Prueba[] pruebas = new Prueba[]
    //{
    //    new Prueba { Name = "Tomato Soup"},
    //    new Prueba { Name = "Yo-yo"},
    //    new Prueba { Name = "Hammer"}
    //};

    public IQueryable<Prueba> GetAllPruebas()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<OracleDbContext>());

        using (var ctx = new OracleDbContext())
        {
            return ctx.Pruebas;
        }
    }
}


(如您所见,我有一个“ pruebas”列表,当我返回该列表时,http服务有效)

这是我的OracleDbContext

public class OracleDbContext : DbContext
{

    public DbSet<Prueba> Pruebas { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("DATA");
    }
}

最佳答案

您正在返回IQueryable对象。返回后,将退出Using语句,该语句将关闭Context。在退出using语句之前,您需要使用.ToList()进行枚举。这将在上下文仍处于打开状态时执行查询。

更改为此:

public List<Prueba> GetAllPruebas()
{
   using (var ctx = new OracleDbContext())
    {
        return ctx.Pruebas.ToList();
    }
}


同样,您应该在上下文的构造函数中添加初始化器,而不是在GetAllPruebas方法中添加,如下所示:

public class OracleDbContext : DbContext
{
    public OracleDbContext()
    {
        Database.SetInitializer<OracleDbContext>(new DropCreateDatabaseAlways<OracleDbContext>());
    }

    public DbSet<Prueba> Pruebas { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("DATA");
    }
}

10-08 15:56