我对导航属性在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”。
即使没有它,此代码仍然有效。
所以我的问题是:
导航属性通过使用连接语句调用数据库来工作,这是正确的吗?
当你使用像item.user_sender.username这样的导航属性时,是否是对数据库的单独调用?这意味着foreach正在为每个项目调用DB,对吧?
在上面的代码中,我是否为每个foreach项目调用了数据库?如果我添加了.Include(“user_reciever”)。Include(“user_sender”),那是否意味着我不会为每个foreach项目调用Db? (我猜不是因为所有项目都已预先加载了一个db join语句)
这是运行此代码的有效方法吗?我不想显示包含另一个表中的用户名的用户消息。我使用Sender_id,Reciever_id查找发送者以及收到的人。
感谢您的帮助。
答案 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 */ }).