2013-12-12 65 views
2

這是我的第一篇文章:)我是MVC .NET的新手。並且對於實體框架功能和性能有一些問題。問題直列...實體框架,DbSet <T>,Dispose()性能問題

class StudentContext : DbContext 
{ 
    public StudentContext() : base("myconnectionstring") {}; 
    public DbSet<Student> Students {get; set; } 
    ... 
} 

問:是否DbSet從數據庫中讀取學生表中的所有記錄,並將其存儲在收集學生(即在內存中)?或者它只是持有一個到這個表的連接,並且(記錄)提取是在SQL針對數據庫執行時完成的?

爲以下幾點:

private StudentContext db = new StudentContext(); 
Student astudent = db.Students.Find(id); 

var astudent = from s in db.Students 
       where s.StudentID == id) 
       select s; 

問:哪些是獲得更好的性能?我不確定Find方法是如何在集合中工作的。

問題:數據庫連接何時關閉?在Dispose()方法調用期間? 如果是這樣,我應該爲具有數據庫上下文實例的類調用Dispose()方法嗎?我讀過這裏使用使用塊。

我猜一個Controller類的get實例化,包括數據庫訪問的工作,調用它的關聯視圖,然後(控制器)超出範圍並從內存中卸載。或者garbase收藏家。但最好調用Dispose()來明確地進行清理。

+0

糾正我,如果我錯了,但'DbSet '意味着你使用實體框架,而不是LINQ to SQL,不是嗎? – MarcinJuraszek

+0

是的,使用EF。對不起,這些條款是新的。我應該說EF和LINQ的聲明。 –

+0

好的,我編輯了你的問題來匹配。 – MarcinJuraszek

回答

3

Find方法在DbContext中查找具有指定鍵的實體。如果沒有匹配的實體已經加載,則DbContext將使用SELECT TOP 1查詢來獲取實體。

運行db.Students.Where(s => s.StudentID == id)會得到一個包含從類似於SELECT * FROM Students WHERE StudentID = @id的SQL查詢返回的所有實體的序列。這應該是相當快的;您可以通過使用db.Students.FirstOrDefault(s => s.StudentID == id)來加速它,這會在SQL查詢中添加TOP 1

如果您從相同的DbContext中多次加載相同的實體,則使用Find會更有效。除此之外FindFirstOrDefault幾乎相當。

在任何情況下,上下文都加載整個表格,也不支持打開連接。我相信DbContext會保留一個連接,直到DbContext處理完畢,但它會在需要解析查詢時按需打開和關閉連接。

+0

是的,謝謝。並從http://msdn.microsoft.com/en-us/library/bb896325%28v=vs.100%29.aspx實體框架僅在需要時纔打開連接,例如執行查詢或調用SaveChanges,以及然後在操作完成時關閉連接。 調用以下任一方法將打開連接:1. SaveChanges或ObjectContext上的刷新。 2. FirstOrDefault或ObjectQuery上的第一個。 3.在EntityCollection上加載。 4.在EntityReference上加載。 5。任何語言集成查詢(LINQ)方法或ObjectQuery查詢構建器方法,例如Where,OrderBy或Select。 –

+1

該列表中的第5個數字不正確;只有在IQueryable *枚舉時纔會打開連接,而不是在調用查詢方法時打開連接。 –