视图上的实体框架导航属性

时间:2014-01-21 03:59:16

标签: c# sql asp.net-mvc entity-framework entity-framework-4

我对导航属性在MVC上的工作方式感到有些困惑。

我们来看看这段代码:

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());

我排除了Include字段,因此不包括“user_reciever”和“user_sender”。

然而,在我的观点中,我有这个:

@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>

注意我是如何使用此代码的:username = item.user_sender.username,但是,我没有在Db Call上包含“user_sender”。

即使没有它,此代码仍然有效。

所以我的问题是:

  1. 导航属性通过使用连接语句调用数据库来工作,这是正确的吗?

  2. 当你使用像item.user_sender.username这样的导航属性时,是否是对数据库的单独调用?这意味着foreach正在为每个项目调用DB,对吧?

  3. 在上面的代码中,我是否为每个foreach项目调用了数据库?如果我添加了.Include(“user_reciever”)。Include(“user_sender”),那是否意味着我不会为每个foreach项目调用Db? (我猜不是因为所有项目都已预先加载了一个db join语句)

  4. 这是运行此代码的有效方法吗?我不想显示包含另一个表中的用户名的用户消息。我使用Sender_id,Reciever_id查找发送者以及收到的人。

  5. 感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

  

导航属性通过使用join语句调用DB来工作,       那是对的吗?

取决于您如何加载导航属性。如果您使用Include方法加载它们,那么它将使用join s。如果这些属性是延迟加载的,则不需要join

  

使用item.user_sender.username之类的导航属性时,       是对DB的单独调用?这意味着foreach是       为每个项目调用数据库,对吧?

是。如果您不使用include方法

  

在上面的代码中,我是否为每个foreach项目调用数据库?如果我       添加了.Include(“user_reciever”)。包括(“user_sender”),会       这意味着我不会为每个foreach项目调用Db? (我是       猜测不,因为所有项目都已预先加载了一个数据库       加入声明)

  

这是运行此代码的有效方法吗?我不想显示       包含另一个表中的用户名的用户消息。我用户       Sender_id,Reciever_id找出谁发送了它以及谁收到它。

使用Include方法在这里更有效。您可以将查询结果投影为仅加载必需的字段。这比使用Include方法更快。

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 */ }).