简体   繁体   中英

Entity Framework Navigation Properties on Views

I am a little confused on how navigation properties work on MVC.

Let's take a look at this code:

var messages = db.messages // .Include("user_reciever").Include("user_sender")
    .Where(M => M.receiver_id == _User.id && M.delete_code != 1)
    .OrderByDescending(M => M.timestamp);

return View(messages.ToList());

I excluded the Include field so "user_reciever" and "user_sender" are not included.

However, in my View, I have this:

@foreach (var item in Model)
{
    var tr_style = item.message_read == false ? "font-weight:bold" : "";
    <tr style="@tr_style">
        <td>
            <input type="checkbox" name="MessageIds" id="MessageIds" value="@item.id"/>
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.message_read)
        </td>
        <td>
            @Html.ActionLink(item.user_sender.username, "Overview", "User", new { username = item.user_sender.username }, null)
        </td>
        <td>
            @Html.ActionLink(item.subject, "Details", new { id = item.id })
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.timestamp)
        </td>
    </tr>
}
</table>

Notice how I am using this code: username = item.user_sender.username, however, I did NOT include the "user_sender" on the Db Call.

Even without it, this code still works.

So my questions are:

  1. Navigation Properties work by calling the DB using a join statement, is that correct?

  2. When you use Navigation Properties like item.user_sender.username, is that a separate call to the DB? That would mean that foreach is calling the DB for each item, right?

  3. In that code above, am I calling the DB for every foreach item? If I added the .Include("user_reciever").Include("user_sender"), would that mean I won't be calling the Db for every foreach item? (I am guessing no because all the items are already pre-loaded with one db join statement)

  4. Is this an effective way to run this code? I wan't to display the user messages that contains the Username from another table. I user Sender_id, Reciever_id to find out who sent it and who recieved it.

Thank you for all the help.

Navigation Properties work by calling the DB using a join statement, is that correct?

Depends on how you load the navigational property. If you use Include method to load them then it will use join s. If these properites are lazy loaded it will not require a join

When you use Navigation Properties like item.user_sender.username, is that a separate call to the DB? That would mean that foreach is calling the DB for each item, right?

Yes. If you do not use the include method

In that code above, am I calling the DB for every foreach item? If I added the .Include("user_reciever").Include("user_sender"), would that mean I won't be calling the Db for every foreach item? (I am guessing no because all the items are already pre-loaded with one db join statement)

Yes.

Is this an effective way to run this code? I wan't to display the user messages that contains the Username from another table. I user Sender_id, Reciever_id to find out who sent it and who recieved it.

Using the Include method is more effective here. You can project the query results to load only the required fields. This will be faster than using the Include methods.

var messages = db.messages
                         .Where(M => M.receiver_id == _User.id && M.delete_code != 1)
                         .OrderByDescending(M => M.timestamp)
                         .Select(m => new MessageModel { Id = m.id, Sender = m.user_sender.username, /* etc */ }).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM