1

In my application the structure looks like this:

public class Route
{
    [Key]
    public int RouteId {get; set;}
    public Address virtual AddressA {get; set;}
    public Address virtual AddressB {get; set;}
}

public class Address 
{
    [Key]
    public int AddressId {get; set;}
    public string Name {get; set;}
}

and

public class DbConnection : DbContext
{
    public DbSet<Route> Routes{get; set;}
    public DbSet<Address> Addresses{get; set;}
}

I take the data like this:

public ActionResult GetList()
{
    using(DbConnection db = new DbConnection)
    {
        var query = db.Routes.ToList();
    }

    return PartialView(query);
}

and then display the data:

@foreach (var r in Model)
{
    <div>@r.AddressA.Name - @r.AddressB.Name</div>
}

However the problem is that the View/PartialView is rendered after the using brackets close so it tries to access AddressA's Name and this gives me an error because the table was not loaded full. Yes, I can do:

public ActionResult GetList()
{
    using(DbConnection db = new DbConnection)
    {
        var query = db.Routes.Include("Address").ToList();
    }

    return PartialView(query);
}

However, when I make this a tiny bit more complex query, the code starts getting really ugly with all the includes. Is there some way to overcome this so with one simple line of code or something less ugly than .Include("A").Include("B").Include("X.Y.Z")?

2
  • You can use the lambda version of Include. Or you can turn off lazy loading completely. Or the best solution is to use viewmodels and fill them with the required data inside the using block. Commented Apr 11, 2013 at 19:30
  • If you could move your answer suggesting viewmodels, I could be able to accept :) I went this way and am pretty happy with it :) Commented Apr 14, 2013 at 12:10

1 Answer 1

1

You can use the lambda version of Include which only provides type safety but doesn't solve your problem.

Or you can turn off lazy loading completely which will solve your "Include problems", but will disable some valid use case of the lazy loading feature.

Or the best solution is to not use your entities in the views but create view-models and fill them with the required data inside the using block.

So your view-model would look like this:

public class AddressViewModel
{
   public string AddressAName { get; set; }
   public string AddressBName { get; set; }
}

Then in your controller you can create the viewmodel:

public ActionResult GetList()
{
    using(DbConnection db = new DbConnection)
    {
        var query = db.Routes.Select(r => 
           new AddressViewModel 
               { 
                   AddressAName = r.AddressA.Name, 
                   AddressBName = r.AddressB.Name, 

               }).ToList();
    }

    return PartialView(query);
}

Which can be easily used in your view:

@foreach (var r in Model)
{
    <div>@r.AddressAName  - @r.AddressBName</div>
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your help and a nice thorough answer :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.