EF上的数据库连接错误

Chr*_*oot 1 c# entity-framework asp.net-web-api

我是实体框架的新手,我正在编写一个基于web api的网站(连接到mssql)的问题.我一直在看似随机的错误(大多数似乎与数据库有关).这些错误最常发生在网站首次发布时,但有时会发生在自上次发布以来已有数小时的情况.选择的错误:

  • 操作无效.连接已关闭.
  • 已经有一个与此命令关联的打开DataReader,必须先关闭它.
  • 连接没有关闭.连接的当前状态是连接.
  • 在创建模型时无法查看上下文
  • 基础提供商未能开启

我的上下文如下:

public class Context : DbContext
{

    public Context() : base("name=DefaultConnection")
    {
    }

    public override int SaveChanges()
    {
        DateTime now = DateTime.Now;
        foreach (ObjectStateEntry entry in (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
        {
            if (!entry.IsRelationship)
            {
                IHasUpdated updated = entry.Entity as IHasUpdated;
                if (updated != null)
                    updated.updated = now;
            }
        }
        return base.SaveChanges();
    }

    public DbSet<Branch> Branches { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<UsefulLink> UsefulLinks { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

还有更多的DbSets.我应该为每个人创建一个单独的上下文吗?

我的一个基本控制器:

 public class UsefulLinksController : ApiController
 {
    private Context db = new Context();

    [ResponseType(typeof(UsefulLinksWrapper))]
    public IHttpActionResult GetUsefulLinks([FromUri]UsefulLinkParams prams)
    {   
        UsefulLinksWrapper wrapper = new UsefulLinksWrapper();
        Meta meta = new Meta();
        IQueryable<UsefulLink> query = db.UsefulLinks;

    if (prams.sortBy == null)
        {
            prams.sortBy = "ID";
        }

        // Paging
        query = query.OrderBy(prams.sortBy + " " + prams.sortDirection).Skip(prams.offset - 1).Take(prams.limit);

        List<UsefulLink> data = query.ToList();

        meta.totalCount = query.Count();
        meta.offset = 1;
        meta.limit = prams.limit;
        wrapper.meta = meta;
        wrapper.data = data;

        return Ok(wrapper);

    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }

    private bool UsefulLinkExists(int id)
    {
        return db.UsefulLinks.Count(e => e.ID == id) > 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在本地运行网站时似乎没有看到这些错误,虽然我们有两个人在发布时遇到它,所以问题可能来自多个用户?

Ayo*_*o I 9

Chris,我注意到你的控制器中你正在与控制器类中的所有方法共享你的db上下文.

这通常不是实体框架中的最佳实践(请参阅:EntityFramework 4 ObjectContext Lifetime).你应该尽可能简短地保持你的背景.让上下文保持活动以在多个方法之间共享可能会导致上面列出的许多错误.

我建议尝试实例化上下文的新实例,而不管它在何处使用并快速处理它.

这通常应该导致更稳定的行为.

所以下面:

class SomeClass
{
   private context = new Context(); //sharing your context with all methods
   public someMethod()
   {
      context.doSomething;
   }

   public someMethod2()
   {
      context.doSomething;
   }
}
Run Code Online (Sandbox Code Playgroud)

应成为:

class SomeClass
{

   public someMethod()
   {
      Context context = new Context(); //now your context is declared and disposed of within each method
      context.doSomething;
   }

   public someMethod2()
   {
      Context context = new Context(); //now your context is declared and disposed of within each method
      context.doSomething;
   }
}
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,您可以使用using构造来确保您的上下文被正确处理:

class SomeClass
{
   public someMethod3()
   {
      using(Context context = new Context()) //now wrapping the context in a using to ensure it is disposed
      {
         context.doSomething;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我建议尝试上述更改,看看你的行为是否更稳定.