Good practices in using DB connections via Entity Framework

7

When defining the context class in the Entity Framework (example):

public class Context : DbContext
{
    public DbSet<Usuario> Usuarios { get; set; }
    public DbSet<Categoria> Categorias { get; set; }
}

And used in DAO classes or Controllers:

private Context db = new Context();

What is the best way to use the reference to Context ? Would it be more performative if db was static ? Home Is there relevant literature on this issue related to an environment with many competing users?

    
asked by anonymous 25.02.2014 / 17:12

4 answers

6

DbContext is not a thread-safe class, so it should not be used as static (which I imagine to be singleton). Attached objects in this context are also not thread-safe , which can create conflicts.

This makes the idea of using a context by Controller a good idea, since by destroying DbContext of each Controller , the Dispose method is called for every DbSet , and consequently for each object connected to each DbSet . This ensures that any pending modifications are properly resolved at the expiration of the object.

Still, if it is interesting to use a standard

25.02.2014 / 17:32
5

A long time ago I studied and read a lot about using the EntityFramework and I came up with a programming methodology, where I instantiate the context in each method, past, if necessary, context by reference to other methods I call. I always try to use the using statement, thus ensuring that after the execution of the instructions that need the same context it is freed from memory and releasing the connection. I do not know how much this way of programming is efficient, but in the applications I already have, I've never had a problem with performance.

private Usuario getUser(int id)
{
    Usuario usuario = null;
    using (var db = new Context()) 
    {    
       usuario  = (from x in db.Usuarios
            where x.UsuarioID == id && !x.Excluido
            select x).FirstOrDefault();
    }
    //outras instruções que não necessitam de conexão com o banco

    return usuario;
}
    
25.02.2014 / 22:27
5

Generally DataContext is instantiated on each object (a CRUD of Users for example, therefore Class Users). It is not good practice to use it as singleton or static [ ref 1 ), ( sigleton! = Static ). In fact singletons should be minimized in a [ ref 2 ) application.

public class Usuarios
{
    private Context db = new Context();

    private Usuario getUser(int id){
        return (from x in db.Usuarios
                where x.UsuarioID == id && !x.Excluido
                select x);
    }

    private IEnumerable<Usuario> getUserList(){[..]}

    private bool SaveUser(Usuario info){[..]}
    [..]
}

Some people instantiate each method:

    private Usuario getUser(int id){
        var db = new Context();
        return (from x in db.Usuarios
                where x.UsuarioID == id && !x.Excluido
                select x);
    }

and there are those who instantiate in each method deallocating with using :

    private Usuario getUser(int id){
        Usuario result = null;

        using (var db = new Context()){
            result = (from x in db.Usuarios
                where x.UsuarioID == id && !x.Excluido
                select x);
        }

        return result;
    }

But as already discussed in SO-english , in practice it becomes unnecessary to deallocate the Context variable after use since Garbage Collector already takes care of it soon after realizing the end of the use of the Context variable. Incidentally for this cause, not only unnecessary as an anti-pattern ( anti-pattern ) by overuse.

References:

1
link link link

2 link
link
link

    
25.02.2014 / 18:02
3

If you create a context for each object, as in the first example, you have a problem if the objects are associated, eg Pessoa and Endereco , where Endereco points to Pessoa . So when you have an instance of Pessoa on a context and an instance of Endereco on another context and need to connect that Endereco to Pessoa , it will give error saying that it can not because it's part of contexts different.

As in the second example, it is only possible if you can solve everything in one method. Horrible! Example: I can have a method that searches for person by cpf.

Pessoa.pesquisaCpf(string cpf)

In this method I return a person and need to do a search using a context . Then I need to create a Endereco , using my same example, and I use the builder of Address, which will create another context. There it will be an error.

To solve all this I am still using only a context created in the system login. I'm not happy about this, because changes made to the system by one user are not seen by another user on another machine until it resumes login. This I'm trying to fix.

    
29.05.2014 / 17:46