2014-01-21 25 views
1

我對導航屬性如何在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()); 

我排除了包含字段,以便「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> 

通知我如何使用此代碼:用戶名= item.user_sender.username,但是,我並沒有包括在DB中的「user_sender」呼叫。

即使沒有它,此代碼仍然有效。

所以我的問題是:

  1. 導航通過使用連接語句調用數據庫屬性的工作,是正確的?

  2. 當您使用像item.user_sender.username這樣的導航屬性時,是否對數據庫單獨調用?這意味着每個項目都會調用數據庫,對吧?

  3. 在上面的代碼中,我是否爲每個foreach項目調用數據庫?如果我添加.Include(「user_reciever」).include(「user_sender」),這是否意味着我不會爲每個foreach項目調用Db? (我猜沒有,因爲所有的項目已經預先加載了一個db連接語句)

  4. 這是一種運行此代碼的有效方法嗎?我不想從其他表中顯示包含用戶名的用戶消息。我使用Sender_id,Reciever_id找出誰發送了它,誰收到它。

謝謝你的一切幫助。

回答

0

導航屬性使用連接語句調用數據庫, 是否正確?

取決於您如何加載導航屬性。如果您使用Include方法加載它們,那麼它將使用join s。如果這些性質在懶惰加載它不會需要join

當您使用導航屬性像item.user_sender.username, 是對DB單獨調用?這意味着每個項目調用數據庫的foreach是 ,對不對?

是的。如果你不使用include方法

在上面的代碼中,我是否爲每個foreach項調用數據庫?如果我在 中添加了.Include(「user_reciever」).include(「user_sender」),那麼 這意味着我不會爲每個foreach項目調用Db?(我猜 沒有因爲所有的項目都已經預裝了1分貝 連接語句)

是。

這是運行此代碼的有效方法嗎?我不想顯示包含另一個表中的用戶名的 用戶消息。我用戶 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 */ }).