1

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);
    }
3
  • 2
    You should use a profiler aimed at the Entity Framework which can show you the traffic and queries it generates. Commented Jan 28, 2014 at 17:18
  • 1
    What database are you using? Microsoft SQL Server has a built-in analysis tool that will show you the SQL text of database queries as they are made. I suspect other databases may have similar tools. Commented Jan 28, 2014 at 17:20
  • thank you for help , but can you know if this code at view is hit database every time or not ? Commented Jan 28, 2014 at 17:37

3 Answers 3

1

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).

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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.

2 Comments

thank you for your help, ill try that , but if you noticed the code at my controller i include the "AlbumsLocs" to prevent lazy loading , but i need to make expression at my view to get specific element i want, that's all
it may be another property that is causing it, or even may be a property within "AlbumsLocs"

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.