3

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 an async 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.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Vladyslav Furdak
  • 1,765
  • 2
  • 22
  • 46
  • Post more complete code. As you might imagine this piece of code looks completely innocent and nothing can be diagnosed from it. – usr Oct 31 '15 at 14:35
  • @usr I added the code – Vladyslav Furdak Oct 31 '15 at 14:41
  • OK. Now the full exception ToString please because the code looks fine to me. – usr Oct 31 '15 at 14:43
  • It seems the reason is the following error `Additional information: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)` But Management studio has been connected without problems. Is the following connection string correct for win auth `Data Source=host;Initial Catalog=database;Integrated Security=True;` ? – Vladyslav Furdak Oct 31 '15 at 15:13
  • Sounds like the two errors are not related. Again, post the full ToString output. Lots of information in there. – usr Oct 31 '15 at 18:47

2 Answers2

0

If your management studio has been able to connect successfully to the database then do this. Run your management studio and before you connect to the database copy out the full "Server name" and use this to replace your "host" and confirm that the actual name of the particular database you are trying to connect to is called "database" and if not replace "database" with that name. Finally if you management studio requires a user name and password to connect to the database then you have to include those as well. From the error you are getting the problem is connecting to your database. Let me know how it goes.

Siwoku Adeola
  • 106
  • 12
0

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:

  • You should be returning a ViewModel or a data model that represents a database table or view you are querying, in this case MyDbSet, not Model.
  • You should be using the db instance declared generically for the class.
  • You should define what 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://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);
    }
    

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.

vapcguy
  • 7,097
  • 1
  • 56
  • 52