为什么在将lazy-loaded属性显式设置为null时会出现ObjectDisposedException?

时间:2016-08-24 13:17:18

标签: c# entity-framework entity-framework-6

在显式设置延迟加载的属性时,我不应该避免这个特殊问题吗? 另外值得一提的是,在调试时,行config.Farm = null有时会失败。农场保留为先前分配的代理值。此外,有时一切都工作为例外(通常如果我调试缓慢)。

我错过了什么?

有问题的课程:

[Table("statusconfig")]
public class StatusConfig
{
        [Key]
        public long Id { get; set; }
        public long Farm_Id { get; set; }
        [ForeignKey("Farm_Id")]
        public virtual Farm Farm { get; set; }

        // And other columns
} 

我的方法:

public StatusConfig GetOrCreate(long farmId)
        {
            using (var unitOfWork = _unitOfWorkFactory.Create())
            {
                var config =
                    _statusConfigRepository.Get(unitOfWork)
                        .FirstOrDefault(statusConfig => statusConfig.Farm_Id == farmId);
                if (config != null)
                {
                    config.Farm = null;
                    return config;
                }
                config = new StatusConfig
                {
                    LastUpdated = DateTime.UtcNow,
                    Farm_Id = farmId
                };
                _statusConfigRepository.Add(unitOfWork, config);
                unitOfWork.Commit();
                return config;
            }
        }

我的方法用于访问数据库的方法:

public IQueryable<T> Get(IUnitOfWork unitOfWork)
{
    return unitOfWork.GetDbSet<T>();
}
public DbSet<T> GetDbSet<T>() where T : class
{
    return _centralDbContext.Set<T>();
}

异常消息:

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
  "ExceptionType": "System.InvalidOperationException",
  "StackTrace": null,
  "InnerException": {
    "Message": "An error has occurred.",
    "ExceptionMessage": "Error getting value from 'Farm' on 'System.Data.Entity.DynamicProxies.StatusConfig_C1AB21464AB7963C159323DD5304227C407A8689577431C20C5771DDE7B5CA55'.",
    "ExceptionType": "Newtonsoft.Json.JsonSerializationException",
    "StackTrace": "   vid Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)\r\n   vid Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)\r\n   vid Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n   vid Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n   vid Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n   vid Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n   vid Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)\r\n   vid System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   vid System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   vid System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n   vid System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- Slut på stackspårningen från föregående plats där ett undantag utlöstes ---\r\n   vid System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   vid System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   vid System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n   vid System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()",
    "InnerException": {
      "Message": "An error has occurred.",
      "ExceptionMessage": "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.",
      "ExceptionType": "System.ObjectDisposedException",
      "StackTrace": "   vid System.Data.Entity.Core.Objects.ObjectContext.get_Connection()\r\n   vid System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)\r\n   vid System.Data.Entity.Core.Objects.ObjectQuery`1.Execute(MergeOption mergeOption)\r\n   vid System.Data.Entity.Core.Objects.DataClasses.EntityReference`1.Load(MergeOption mergeOption)\r\n   vid System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()\r\n   vid System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)\r\n   vid System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__2(TProxy proxy, TItem item)\r\n   vid System.Data.Entity.DynamicProxies.StatusConfig_C1AB21464AB7963C159323DD5304227C407A8689577431C20C5771DDE7B5CA55.get_Farm()\r\n   vid GetFarm(Object )\r\n   vid Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
    }
  }
}

1 个答案:

答案 0 :(得分:1)

我通过使用Include急切加载关系Farm来解决这个问题。在此之后,我可以毫无问题地选择将其包含在响应中,或者将其设置为null,就像我之前尝试过的那样。仍然不明白为什么我以前的方法没有按预期工作。

var config = _statusConfigRepository.Get(unitOfWork).Include(statusConfig => statusConfig.Farm)
                    .FirstOrDefault(statusConfig => statusConfig.Farm_Id == farmId);