2010-11-17 19 views
25

Tôi đang sử dụng EF 4 để lấy danh sách Nhân viên.System.ObjectDisposedException: Trường hợp ObjectContext đã được xử lý và không còn có thể được sử dụng cho các hoạt động yêu cầu kết nối

public ContentResult AutoCompleteResult(string searchText) 
{ 
    List<Employee> list = Employee.GetAllCurrentEmployees(); 
    List<Employee> filteredEmployees = list 
     .Where(x => x.GetName().ToLower().Contains(searchText.ToLower())) 
     .ToList(); 

    JavaScriptSerializer jsonSerializer = new JavaScriptSerializer(); 
    var jsonString = jsonSerializer.Serialize(filteredEmployees).ToString(); 
    return Content(jsonString); 
} 

Danh sách được truy xuất OK, nhưng khi tôi sắp xếp, tôi nhận ngoại lệ này;

System.ObjectDisposedException: The ObjectContext instance has been 
disposed and can no longer be used for 
operations that require a connection. 
    Generated: Wed, 17 Nov 2010 16:06:56 GMT 

System.ObjectDisposedException: The ObjectContext instance has been 
disposed and can no longer be used for operations that require a connection. 
at 
System.Data.Objects.ObjectContext.EnsureConnection() 
at 
System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)  at 
System.Data.Objects.ObjectQuery`1.Execute(MergeOption mergeOption)  at 
System.Data.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption) at 
System.Data.Objects.DataClasses.EntityCollection`1.Load(MergeOption mergeOption)  at 
System.Data.Objects.DataClasses.RelatedEnd.Load() at 
System.Data.Objects.DataClasses.RelatedEnd.DeferredLoad() at 
System.Data.Objects.DataClasses.EntityCollection`1.System.Collections.IEnumerable.GetEnumerator() at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat 
serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat 
serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat 
serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object 
o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat 
serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, 
SerializationFormat 
serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat 
serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object 
o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat 
serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object 
obj, StringBuilder output, SerializationFormat serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object 
obj, SerializationFormat serializationFormat)  at 
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj)  at 
SHP.Controllers.EmployeeController.AutoCompleteResult(String searchText) in C:\Documents and Settings\geoffreypayne\My Documents\Visual Studio 
2010\Projects\MVC\SHP\SHP\Controllers\EmployeeController.cs:line 
623  at lambda_method(Closure , ControllerBase , Object[])  at 
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at 
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext 
controllerContext, IDictionary`2 parameters)  at 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext 
controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)  at 
System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.InvokeActionMethodWithFilters>b__a() 
at 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 
filter, ActionExecutingContext preContext, Func`1 continuation)  
at 
System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<>c__DisplayClassf.<InvokeActionMethodWithFilters>b__c() at 
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)  at 
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext 
controllerContext, String actionName) 

Tôi thấy điều này rất kỳ quặc. Tôi đã lấy danh sách nhân viên và DataContext đã được xử lý. Vậy tại sao tôi lại gặp lỗi này?

+1

bạn có thể cung cấp đầy đủ các ngăn xếp dấu vết? –

Trả lời

22

Có vẻ như bạn có một số thuộc tính mối quan hệ được tải nhẹ nhàng chưa được tải (có liên quan đến hiệu suất "n + 1" liên quan). Bạn có thể thử eager loading để xem điều này có hữu ích hay không; nếu không, hãy tải dữ liệu rõ ràng cho từng mục trong danh sách, trước bạn đóng bối cảnh đối tượng.

+0

Tôi muốn giữ tải chậm và lọc ra các đối tượng mà tôi không cần. Tôi nghĩ rằng đánh giá từ câu trả lời của bạn rằng serialization không hoạt động vì các đối tượng còn lại là null vì tải lười biếng. Tôi có thể tạo một lớp chỉ với các thuộc tính mà tôi muốn và tạo một danh sách từ đó. Tôi tự hỏi nếu có một cách tốt hơn, rằng tôi không cần phải tạo ra một lớp học như vậy? – arame3333

+2

@ arame3333 - kể từ khi bạn đang nói về 'JavaScriptSerializer', một loại vô danh sẽ làm độc đáo - chỉ cần' chọn mới {row.Foo, row.Bar} 'etc –

+1

Bạn có thể vui lòng xây dựng trên" nếu không, tải dữ liệu rõ ràng cho mỗi mục trong danh sách "? Cảm ơn. – PeterX

1

Có vẻ như một số đánh giá tải chậm hoặc bị trì hoãn đang xảy ra; bạn không thể giả định các đối tượng được "nạp" cho đến khi bạn thực sự cố gắng đọc từ chúng.

Bạn cần duy trì DataContext cho đến khi bạn xử lý hoàn toàn các đối tượng được truy xuất từ ​​cơ sở dữ liệu để tránh các lỗi này.

1

Tôi đã gặp vấn đề tương tự và có thể giải quyết vấn đề bằng cách chọn phép chiếu đối tượng chỉ với các thuộc tính mà người gọi yêu cầu thay vì trả lại đối tượng hoàn chỉnh. Có vẻ như khi bạn có nhiều mối quan hệ trong đối tượng của bạn, bộ nối tiếp sẽ cố gắng điều hướng chúng.

Vì vậy, (giả định bối cảnh đối tượng của bạn được gọi là "Đối tượng") tôi sẽ cố gắng một cái gì đó như thế này:

using (Entities context = new Entities()) 
{ 
     var employeeProjection = (from e in context.Employee 
         select new { e.Id, c.FirstName, e.LastName }).ToList(); 

     return employeeProjection; 
} 
12

Nghĩ rằng tôi sẽ kêu vang trong đây với 2 cent của tôi. Chúng tôi đã có một lớp truy cập dữ liệu rất lớn, và một trong những lập trình viên đã quen sử dụng một tuyên bố sử dụng cho bối cảnh như vậy:

using (EntityModel myContext = EntityConnection) 
{ 
    //code in here to grab data 
} 

Chúng tôi đang sử dụng EntityConnection như một thuộc tính tĩnh phục vụ lên một dbContext mỗi hiện tại HttpContext. Bất kỳ phương thức nào được gọi sau khi sử dụng khối của mình sẽ ném ngoại lệ 'đối tượng ObjectContext đã được xử lý' vì rõ ràng bối cảnh đã được xử lý sau khi gọi phương thức của mình. Vì vậy, nếu bạn chỉ sử dụng một ngữ cảnh thực thể cho mỗi HttpContext, hãy chắc chắn rằng bạn không cho phép bộ thu gom rác thải bỏ nó bằng cách sử dụng một khối sử dụng.

Tôi nhận thấy tôi sẽ ném câu trả lời này vì tôi biết nhiều người sử dụng ngữ cảnh thực thể khác nhau và tôi thấy rất nhiều cách sử dụng các khối trong các mẫu mã trên mạng.

+2

Mario +1 đây là vấn đề tôi đang gặp phải. Tôi đang sử dụng EF để nhận các đề xuất tự động dựa trên ký tự được nhập trong hộp tìm kiếm. Tôi đã cố gắng sử dụng một khối {} nhưng đã nhận được lỗi này. bây giờ tôi chỉ sử dụng một trường hợp đơn lẻ nhưng không chắc chắn về cách xử lý đúng. bạn có thể đưa ra lời khuyên nào không? – Shannow

2

Tôi thích chỉ tải lên một trường hợp mỡ tuyên bố bên ngoài bằng cách sử dụng

Customer _custObj; 
     using (RazorOne rz1 = new RazorOne()) 
     { 
      _custObj = rz1.Customers.FirstOrDefault();  // .Include = Lazy loading 
      // Versus Implicit Load 
      _custObj.AddressReference.Load(); 
      _custObj.Address1Reference.Load(); 
     } 

Sau đó, tôi có thể vượt qua cô vào Xem hoặc bất cứ điều gì helper thực sự muốn cô ấy ..

14

Bạn có thể tắt lười biếng tải để giải quyết vấn đề này.
Bên trong 'sử dụng' khối của bạn, hãy thử này:

yourObjectContext.ContextOptions.LazyLoadingEnabled = false; 

Sau khi thực hiện điều này, tôi đã có thể serialize EF của tôi (DbContext tạo) POCO để JSON mà không cần bất kỳ vấn đề.

* Lưu ý: Vì tôi đã tắt tải chậm ... Tôi kéo các đối tượng liên quan mà tôi cần trước (chủ yếu là với .Include() trong truy vấn của tôi) trước khi đối tượng được tuần tự hóa thành JSON.

+1

Giải pháp đơn giản và sạch sẽ, nhưng lưu ý rằng với các đối tượng liên quan đến phương pháp tiếp cận này (đối tượng con) không được tải tự động. –

+2

Tôi nghĩ rằng mã phải là: 'yourObjectContext.Configuration.LazyLoadingEnabled = false;' theo cách EF6. –

0

Tôi đáng xem xét đối tượng Nhân viên của bạn và đảm bảo bạn không có bất kỳ từ khóa ảo nào dính vào đó. Từ khóa ảo được diễn giải bởi Entity Framework là 'lazy-load'. Chúng tôi cần phải xem lớp nhân viên của bạn để thực hiện một khẳng định tuyệt đối tại sao bạn có thể nhìn thấy ngoại lệ.

0

Tôi đã có một biến thể về vấn đề này. Ngữ cảnh dữ liệu không được đóng lại, nhưng cá thể ngữ cảnh Object đã bị xử lý lỗi đã bị vứt bỏ.

Hóa ra đối tượng có khóa ngoại tự tham chiếu (tức là khóa ngoại được gọi lại vào cùng một bảng). Truy cập thuộc tính điều hướng trong khi nó đề cập đến một null, bạn nhận được ngoại lệ đối tượng được xử lý đối tượng thay vì, nói, một ngoại lệ con trỏ null.

ví dụ:

var a = myObject.Name; // works because myObject still has open object context 
var b = myObject.SelfReference; // throws objectcontext disposed if SelfReference is null 
0

tôi thấy cách tốt nhất để xử lý này và giữ báo cáo kết quả sử dụng, bạn chỉ cần sử dụng bao gồm, xem ví dụ dưới đây:

using (var ctx = new Context(this.connectionString)) { 
    var query = ctx.[maintable] 
    .Include(x => x.[theothertable]) 
    .FirstOrDefaultAsync(u => u.UserName.Equals(userName)); 
} 
Các vấn đề liên quan