Eager Loading - MVC

I have 2 models: (1) FamiliaMáquina (PK: FamiliaId) and (2) TipoMáquina (PK: TipoMáquinaId). The relation between these is: TipoMáquina can have only 1 FamiliaId associated, while FamiliaMáquina can have many TipoMáquinaId associated (one to many relationship).

FamiliaMáquina definition:

        public class FamiliaMáquina
        {
            [Key, Required]
            public int FamiliaId { get; set; }
            public string DescripciónFamilia { get; set; }

            public virtual ICollection<TipoMáquina> TipoMáquina { get; set; }

        }

TipoMáquina definition:

public class TipoMáquina
    {
        [Key, Required]
        public int TipoMáquinaId { get; set; }
        public string DescripciónTipoMáq { get; set; }
        public int FamiliaId { get; set; }

        public virtual FamiliaMáquina FamiliaMáquina { get; set; }

    }

The objetive: Show, programing the FamiliaMáquina controller, a list of FamiliaId (from model 1) and DescripciónTipoMáq (from model 2) associated. For this, the tables have been populated with sample data.

On the FamiliaMaqController (where the association takes places - eager loading):

public class FamiliaMaqController : Controller
    {
        private ApplicationDbContext _context;

        public FamiliaMaqController()
        {
            _context = new ApplicationDbContext();
        }

        protected override void Dispose(bool disposing)
        {_context.Dispose();}

        public async Task<ActionResult> NuevaMQ()
        {
            var fammáquinas = _context.FamiliaMáquinas.Include(c => c.TipoMáquina).AsNoTracking();


            return View(await fammáquinas.ToListAsync());
        }
    }

This is supossed to show on NuevaMQ.cshtml. NuevaMQ code is:

@model IEnumerable<Plataforma.Models.FamiliaMáquina>
@{
    ViewBag.Title = "NuevaMQ";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>NuevaMQ</h2>

<table class="table table-bordered table-hover">
    <thead>
        <tr>
            <th>Familia de Máquina</th>
            <th>Tipo de Máquina</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var fammáquinas in Model)
        {
            <tr>
                <td>@Html.DisplayFor(modelItem => fammáquinas.FamiliaId)</td>
                <td>@Html.DisplayFor(modelItem => fammáquinas.TipoMáquina.DescripciónTipoMáq)</td>
            </tr>
        }
    </tbody>
</table>

I'm getting an error on this line:

@Html.DisplayFor(modelItem => fammáquinas.TipoMáquina.DescripciónTipoMáq

Supposedly, FamiliaID and DescripciónTipoMáq should be listed, however, I get the following warning:

"ICollection doesn't have a definition for 'DescripciónTipoMáq'."

¿Why isn't eager loading working? I've been struggling with this for a while now. It's like this line of code:

var fammáquinas = _context.FamiliaMáquinas.Include(c => c.TipoMáquina).AsNoTracking();

Is not associating the tables but I'm not getting an error there. What I'm getting as a result in the website is:

FamiliaId: 1 DescripciónTipoMáq: System.Data.Entity.DynamicProxies.FamiliaMáquina_EB64915DB33A48C74F57D392EFE55D5AEDC5BF74BE67B819F4737EEB09B6F436

This repeats as many times as items related per FamiliaId. It's like the program is iterating as it should but getting that reference everytime instead of the field value.

Upvotes: 1

Views: 377

Answers (2)

It worked!

I've changed the controller in this way:

        public async Task<ActionResult> NuevaMQ()
        {
            var fammáquinas = _context.TipoMáquinas.Include(c => c.FamiliaMáquina).AsNoTracking();


            return View(await fammáquinas.ToListAsync());
        }

Then, I went to the view to change it accordingly so I could invok the data from FamiliaMáquina and brind the FamiliaId:

    <tbody>
        @foreach (var fammáquinas in Model)
        {
            <tr>
                <td>@Html.DisplayFor(modelItem => fammáquinas.FamiliaId)</td>
                <td>@@Html.DisplayFor(modelItem => fammáquinas.DescripciónTipoMáq)</td>
            </tr>
        }
    </tbody>

also, changed the model of reference at top of the cshtml file:

@model IEnumerable<Plataforma.Models.TipoMáquina>

And as result, the table showed both atributes invoked from diferent tables :) Thanks for the help!

Upvotes: 0

CodeNotFound
CodeNotFound

Reputation: 23200

You've the error in that line

@Html.DisplayFor(modelItem => fammáquinas.TipoMáquina.DescripciónTipoMáq)

Because based on the code of FamiliaMáquina class you're using TipoMáquina which is a collection ICollection<TipoMáquina>. And ICollection<TipoMáquina> likee all ICollection<T> doesn't define DescripciónTipoMáq property that is what the error said:

ICollection doesn't have a definition for 'DescripciónTipoMáq'.

So if you wan't to get the description you need to iterate through each TipoMáquina item and display DescripciónTipoMáq property

Side Note: Avoid using that kind of naming things with accent because you or another developper can lost a lot of time to know why the code doesn't compile and will find that after several minutes that he or she mispelled the name of the varaible.

Upvotes: 2

Related Questions