ahmad alaa
ahmad alaa

Reputation: 13

ASp.NET MVC with Entity Framework: eager and lazy loading in view

Is this code at view really make lazy loading and each time it hits the database? And if it is, is there a solution, and how can I know that if it hit database or not?

@{
    int langId = ViewBag.LangId;

    int i = 0;
    foreach (var item in Model)
    {
        i++;
        <tr class="@(i % 2 == 0 ? "even" : "odd")">
            <td>
                @Html.DisplayFor(modelItem => item.AlbumsLocs.FirstOrDefault(b => b.LanguageId == langId).Title)
            </td>
        </tr>
    }
}

and my controller code is :

public ViewResult Index()
    {
        var moduleItems = db.Albums.Include(x => x.AlbumsLocs).Where(a => a.AlbumVocId == id).ToList();

        return View(moduleItems);
    }

Upvotes: 1

Views: 2353

Answers (3)

Gert Arnold
Gert Arnold

Reputation: 109252

No, there won't be lazy loading, because item.AlbumsLocs will be marked as loaded. So the FirstOrDefault() will not trigger a new load attempt. And you display a primitive property (which I assume Title is), so this won't load a reference. You can easily verify this by monitoring the SQL statements.

However, even though you're OK here, in general you should try to avoid constructs in views that potentially trigger lazy loading. For instance, when you forget the Include, lazy loading will become an issue and the view is far less scalable.

So I would bring more elementary data to the view:

db.Albums.Where(a => a.AlbumVocId == id)
         .Select(a => a.AlbumsLocs.FirstOrDefault(b => b.LanguageId == langId)
                       .Title)

(You should have langId available in the controller as well).

When the view gets more complex, work with view models, so you're in total control of when and where the data is fetched from the database.

This also moves the responsibility of shaping the view data from the view to the controller, where it belongs. (Or in a service, but not in the view).

Upvotes: 1

markpsmith
markpsmith

Reputation: 4918

You can use the System.Diagnostics.Trace class to see the queries that your LINQ is generating. Add this to wherever you use the dbcontext and call the controller method in debug:

#if DEBUG
           YourDbContext.Database.Log = x => Trace.WriteLine(x);
#endif

The SQL generated will be shown in the Output window in Visual Studio 2012.

Upvotes: 1

JC Lizard
JC Lizard

Reputation: 1056

it may or it may not, depending on the model.

to find out, use sql profiler and monitor the requests while running the view and you will find out whether or not it is using lazy loading.

to solve the problem you will have to include every property of the model thats being used on the view.

Upvotes: 0

Related Questions