在创建模型异常时,不能使用上下文

时间:2015-10-31 14:26:12

标签: c# entity-framework async-await

我使用Entity Framework 6.0.0.0收到以下错误消息。

  

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

   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();
       }
 }

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

是否有与此问题相关的建议?我找到了很多答案,但没有发现它们对我有帮助。

2 个答案:

答案 0 :(得分:0)

如果您的管理工作室已成功连接到数据库 然后这样做。在连接到数据库之前运行管理工作室 复制完整的&#34;服务器名称&#34;并用它来取代你的主人&#34;并确认您尝试连接的特定数据库的实际名称是&#34; database&#34;如果没有替换&#34;数据库&#34;用这个名字。最后,如果您的管理工作室需要用户名和密码才能连接到数据库,那么您还必须包含这些。从错误中你得到的问题是连接到你的数据库。让我知道事情的后续。

答案 1 :(得分:0)

您想实现一种连接到数据库的适当方法以处置连接,或使用一个称为“依赖注入”的术语-创建一个可以随时通过任何函数访问的DataContext接口和实例。在控制器中。以下是这两种方法的示例:

处置架构

此体系结构要求您在任何其他函数之前声明DataContext,并在控制器的末尾添加一个Dispose函数。

我在代码中找到并解决了一些特殊的问题:

  • 您应该返回一个表示要查询的数据库表或视图的ViewModel或数据模型,在这种情况下,返回的是MyDbSet,而不是Model
  • 您应该使用为该类通用声明的db实例。
  • 您应该定义filter是什么。数组?一个模型?弦吗?我将假定它是这样的字符串列表:string[] filter = { "Fruits", "Meats", "Dairy" };
  • Where子句在您的查询中可能不正确,但是同样,我不知道您的filter是什么样。这里还有其他示例:https://docs.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文章中详细描述了此过程:

How to inject my dbContext with Unity

主要区别在于您将在控制器的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在存储库类中定义:

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;
    }
}

希望这对您或某人有帮助。