创建模型时无法使用上下文异常

本文关键字:上下文 异常 模型 创建 | 更新日期: 2023-09-27 18:20:04

使用Entity Framework 6.0.0.0时出现以下错误。

在创建模型时不能使用上下文。如果上下文在
内部使用,则可能引发此异常OnModelCreating方法或如果相同的上下文实例由多个线程同时访问。请注意,DbContext和的实例成员相关的类不能保证是线程安全的。它是在async方法中激发的,更新

   public async Task<IList<Model>> GetEntities(filter f)
   {
        using (var db = new MyDbContext())
        { 
           var query = db.MyDbSet.AsQueryable();
            if (f != null && f.field.Any())
               //Exception throwed here
                query = query.Where(a => f.field.Contains(a.field));
        return await query.ToListAsync();
       }
 }

但是,当我试图通过Where子句查找实体时,任何await调用或其他多线程操作都不会执行。

有什么建议与这个问题有关吗?我找到了很多答案,但没有发现它们对我有帮助。

创建模型时无法使用上下文异常

如果您的管理工作室能够成功连接到数据库那就这么做吧。运行管理工作室,然后再连接到数据库复制完整的"服务器名称",并使用它来替换您的"主机",并确认您尝试连接的特定数据库的实际名称称为"数据库",如果没有,则用该名称替换"数据库"。最后,如果您的管理工作室需要用户名和密码来连接到数据库,那么您也必须包括这些。从错误中,您得到的问题是连接到您的数据库。让我知道进展如何。

您想要实现一种正确的连接到数据库的方法来处理连接,或者使用一个称为"依赖注入"的术语-创建一个DataContext的接口和实例,该接口和实例可以由控制器中的任何函数随时访问。以下是两种方法的示例:

处置体系结构

该体系结构要求在任何其他函数之前声明DataContext,并在最后的Controller中添加一个Dispose函数。

我在代码中发现并修复了一些特定的奇怪之处:

  • 您应该返回表示正在查询的数据库表或视图的ViewModel或数据模型,在本例中为MyDbSet,而不是Model
  • 您应该使用为类通用声明的db实例
  • 你应该定义什么是filter。数组?模特?一根绳子?我假设它是一个字符串列表,如下所示:string[] filter = { "Fruits", "Meats", "Dairy" };
  • Where子句在您的查询中可能不正确,但同样,我不知道您的filter是什么样子的。这里还有其他例子:https://learn.microsoft.com/en-us/dotnet/api/system.linq.queryable.where?view=netframework-4.8

    MyDbContext db = new MyDbContext();
    public async Task<IList<MyDbSet>> GetEntities(filter f)
    {
        using (db)
        { 
            var query = null;
            if (f != null && f.field.Any())
            {
                query = db.MyDbSet.AsQueryable().Where((a, index) => a == f);
            }
            return await query.ToListAsync();
        }
    }
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
    

依赖注入

我在另一篇SO帖子中详细描述了这个过程,这里是:

如何用Unity 注入我的dbContext

主要的区别是,你可以在控制器的GetEntities函数中这样做来获得数据:

query = repository.GetMyDbSet.Where((a, index) => a == f);

与上面基本相同,但您不再需要using(db) { ... }语句。

你会有一个界面:

public interface IDataRepository
{
    void SaveChanges();
    IEnumerable<MyDbSet> GetMyDbSet();
}

以及一个存储库类函数,用于将数据返回给您:

public IEnumerable<MyDbSet> GetMyDbSet()
{
    return context.MyDbSet;
}

context是在Repository类中定义的:

public class DataRepository : IDataRepository
{
    private bool disposing;
    private readonly MyDbContext context;
    public virtual void Dispose()
    {
        if (disposing)
        {
            return;
        }
        disposing = true;
        if (context != null)
        {
            context.Dispose();
        }
    }
    public void SaveChanges()
    {
        context.SaveChanges();
    }
    public DataRepository()
    {
        context = new MyDbContext();
        context.Configuration.ProxyCreationEnabled = false;
    }
    public IEnumerable<MyDbSet> GetMyDbSet()
    {
        return context.MyDbSet;
    }
}

希望这能帮助到你或其他人。