I've got the following error using Entity Framework 6.0.0.0
.
The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the
OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe. It is fired inside anasync
method ,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();
}
}
But any await
calls or other multithreading operation is not performed when i try to find my entities by Where
clause.
Are any suggestions related to that issue ? I found a lot of answers but didn't found their helpful for me.
You want to implement a proper method of connecting to your database that disposes the connection, or uses a term called "dependency injection" - creating an interface and instance of the DataContext that is able to be accessed at any time by any function in the controller. Here are examples of the 2 methods:
Dispose Architecture
This architecture requires that you declare your DataContext before any other function, and add a Dispose
function in the Controller at the end.
Some specific oddities I found and fixed in the code:
MyDbSet
, not Model
.db
instance declared generically for the class.filter
is. An array? A model? A string? I'm going to assume it's a list of strings like this: string[] filter = { "Fruits", "Meats", "Dairy" };
The Where
clause might not be correct on your query, but again, I don't know what your filter
looks like. There's other examples here: 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);
}
Dependency Injection
I describe this process thoroughly in another SO post, here:
How to inject my dbContext with Unity
The main difference is you would do something like this in your controller's GetEntities
function to get the data:
query = repository.GetMyDbSet.Where((a, index) => a == f);
Mostly the same as above, but you don't need the using(db) { ... }
statement, anymore.
You would have an interface:
public interface IDataRepository
{
void SaveChanges();
IEnumerable<MyDbSet> GetMyDbSet();
}
and a repository class function to return the data to you:
public IEnumerable<MyDbSet> GetMyDbSet()
{
return context.MyDbSet;
}
And context
is defined in a Repository class:
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;
}
}
Hopefully this helps you or someone.