2013-03-27 35 views
42

Khi nào một người nên gọi DbContext.dispose() với khung thực thể?Khuôn khổ thực thể và bối cảnh xử lý

  1. Phương pháp tưởng tượng này có tệ không?

    public static string GetName(string userId) 
    { 
        var context = new DomainDbContext(); 
        var userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId); 
        context.Dispose(); 
        return userName; 
    } 
    
  2. Đây có phải là tốt hơn?

    public static string GetName(string userId) 
    { 
        string userName; 
        using(var context = new DomainDbContext()) { 
         userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId); 
         context.Dispose(); 
        } 
        return userName; 
    } 
    
  3. Đây có phải là tốt hơn, có nghĩa là, nên người ta không gọi context.Dispose() khi sử dụng sử dụng()?

    public static string GetName(string userId) 
    { 
        string userName; 
        using(var context = new DomainDbContext()) { 
         userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId); 
        } 
        return userName; 
    } 
    
+12

_không nên gọi ngữ cảnh.Đặc biệt() khi sử dụng using() _ luôn đúng. Nó là thừa. –

+0

Cảm ơn bạn đã bình luận. Vì vậy, context.Dispose() chỉ là dự phòng, loại bỏ nó sẽ không có bất kỳ tác dụng? – Sindre

+1

'using' là một ẩn' Dispose() ' –

Trả lời

74

Trong thực tế đây là hai câu hỏi trong một:

  1. Khi nào tôi nên sử dụng Dispose() của một bối cảnh?
  2. Điều gì sẽ là tuổi thọ của bối cảnh của tôi?

Đáp:

  1. Never . using là một ẩn số Dispose() trong khối try-finally. Một tuyên bố riêng biệt Dispose có thể bỏ qua khi ngoại lệ xảy ra trước đó. Ngoài ra, trong hầu hết các trường hợp phổ biến, không gọi số Dispose nào cả (hoặc ngầm hoặc rõ ràng) isn't harmful.

  2. Xem ví dụ: Entity Framework 4 - lifespan/scope of context in a winform application. Tóm lại: tuổi thọ sẽ là "ngắn", bối cảnh tĩnh là xấu.


Theo một số người nhận xét, một ngoại lệ cho quy tắc này là khi một bối cảnh là một phần của một thành phần mà thực hiện IDisposable bản thân và chia sẻ vòng đời của nó. Trong trường hợp đó, bạn sẽ gọi context.Dispose() theo phương thức Dispose của thành phần.

+0

Đây là câu trả lời đúng và tất cả những gì bạn cần biết. Bỏ phiếu lên. –

+0

Cảm ơn, Gert Arnold. Tôi sẽ đọc lên mẫu Đơn vị công việc! – Sindre

+1

Hmmm, không "Không bao giờ" vẫn áp dụng nếu bạn không sử dụng câu lệnh "sử dụng" để bao trùm bối cảnh của bạn (đề cập đến trường hợp 1)? – gitsitgo

0

tôi sẽ sử dụng tùy chọn 3; sử dụng using() sẽ tự động xử lý ngữ cảnh cho bạn. Tùy chọn 2 là xấu. Tùy chọn 1 cũng có thể là ok nhưng Tùy chọn 3 có vẻ dễ đọc hơn.

26

Tôi đã làm theo một số hướng dẫn tốt để sử dụng EF và họ không loại bỏ ngữ cảnh.

Tôi hơi tò mò về điều đó và tôi nhận thấy rằng ngay cả những người được kính trọng Microsoft VIP cũng không vứt bỏ ngữ cảnh. Tôi thấy rằng bạn không phải vứt bỏ dbContext trong tình huống bình thường.

Nếu bạn muốn biết thêm thông tin, bạn có thể đọc this blog post tóm tắt lý do.

10

Vẫn còn tốt hơn:

public static string GetName(string userId) 
{ 
    using (var context = new DomainDbContext()) { 
     return context.UserNameItems.FirstOrDefault(x => x.UserId == userId); 
    } 
} 

Không cần phải trả lại kết quả từ bên ngoài phạm vi using; chỉ cần trả lại ngay lập tức và bạn vẫn sẽ nhận được hành vi xử lý mong muốn.

1

Bạn có thể xác định bối cảnh cơ sở dữ liệu của mình làm trường lớp và triển khai IDisposable. Một cái gì đó như dưới đây:

public class MyCoolDBManager : IDisposable 
{ 
    // Define the context here. 
    private DomainDbContext _db; 

    // Constructor. 
    public MyCoolDBManager() 
    { 
     // Create a new instance of the context. 
     _db = new DomainDbContext(); 
    } 

    // Your method. 
    public string GetName(string userId) 
    {   
     string userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId); 

     return userName; 
    } 

    // Implement dispose method. 
    // NOTE: It is better to follow the Dispose pattern. 
    public void Dispose() 
    { 
     _db.dispose(); 
     _db = null; 
    } 
} 
Các vấn đề liên quan