Entityframework 6 + Lazyloadingenabled + using()

Asked

Viewed 522 times

6

I need a help. My problem is this: I cannot return my object items.

Follow my code for analysis.

Client class

public partial class Cliente
{
    public Cliente()
    {
        this.ClienteEndereco = new HashSet<ClienteEndereco>();
    }

    public int IdCliente { get; set; }
    public string Nome { get; set; }

    public virtual ICollection<ClienteEndereco> ClienteEndereco { get; set;}
}

Class Clienteaddressee

public partial class ClienteEndereco
{
    public int IdClienteEndereco { get; set; }
    public int IdCliente { get; set; }
    public int IdCidade { get; set; }
    public string Endereco { get; set; }

    public virtual Cidade Cidade { get; set; }
    public virtual Cliente Cliente { get; set; }
}

Consultation method

    public IList<T> ListarTudo()
    {
        using (MeuContext context = new MeuContext())
        {
            context.Configuration.LazyLoadingEnabled = false;

            return context.Set<T>().ToList();
        }
    }

When I call my query the Clienteender items return to me Count = 0:

var clientes = repositorioCliente.ListarTudo();

I know that if I put the in the Include("Clienteendereco") query method it will return all my items, but this method is generic, so I changed the method by passing the required includes.

    public List<T> ListaTudo(string[] includes)
    {
        using (MeuContext context = new MeuContext())
        {
            IQueryable<T> query = context.Set<T>();
            if (includes != null)
                foreach (var includeProperty in includes)
                {
                    query = query.Include(includeProperty);
                }
            return query.ToList();
        }
    }

But now, every call I make there in mine Controller (MVC) for all methods I will have to pass the list of necessary includes.

private readonly RepositorioGenerico<Cliente> repositorioCliente = new RepositorioGenerico<Cliente>();

private string[] includes = {"ClienteEndereco","ClienteEndereco.Cidade"};

var Clientes = repositorioCliente.ListaTudo(includes);

Besides thinking my code is getting too polluted I’m having a lot of work to map in all Controllers the Includes necessary, just there in my View not to burst the error of:

"The Objectcontext instance has been disposed and can no longer ...."

There is some other way to bring the items without me needing to use Includes?

1 answer

4

If you are having a lot of work, it means you are using the wrong tool, and this is evident from your explanation.

I guess I won’t be able to get tired of saying Entity Framework is already a repository, so you don’t need to implement another repository. Look at the answers I’ve given about:

About Model Cliente

This does not need to be done. The Entity Framework controls the browsing properties automatically, so nothing needs to be initialized. The part below can be removed from the code:

public Cliente()
{
    this.ClienteEndereco = new HashSet<ClienteEndereco>();
}

About the Consultation Method

There’s no reason for you to disable the Lazy Load at this time. It is only justified if you have a very large mass of records to use, which is hardly the case.

Besides, this building here:

return context.Set<T>().ToList();

Make the Entity Framework perform a FULL TABLE SCAN in your database. The correct thing is to mount the sentence in the DbSet and only use .ToList() with due parameterization. That is, this construction is lousy for performance.

About the problem of Include

The problems you’re having occur at the insistence of you using a generic repository where you don’t need it.

This type of construction is completely unnecessary and should be abandoned:

public List<T> ListaTudo(string[] includes)
{
    using (MeuContext context = new MeuContext())
    {
        IQueryable<T> query = context.Set<T>();
        if (includes != null)
            foreach (var includeProperty in includes)
            {
                query = query.Include(includeProperty);
            }
        return query.ToList();
    }
}

If I need to list everything, such as clients, I can do only:

var clientes = context.Clientes.ToList();

If I need to upload customer data and want to load by JOIN addresses, I can do as follows:

var clientes = context.Clientes.Include(c => c.ClienteEndereco).ToList();

That is to say, there is no reason to continue an implementation with generic repository. Simply use the Entity Framework as shown in the tutorials that data optimization occurs naturally in almost all cases.

For other cases, ask here on the site.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.