2013-02-26 1 views
0
код

Объект:Entity Framework GetDatabaseValues ​​() бросить NullReferenceException

public class ParticipatingService 
{ 
    [Key] 
    public int Id { get; set; } 

    public int OptimisticVersion { get; set; } 

    [DisplayName("Receiver site")] 
    public int? TargetSiteId { get; set; } 
    [DisplayName("Receiver site")] 
    public virtual Hospital TargetSite { get; set; } 

    [DisplayName("Provider site")] 
    public int? SourceSiteId { get; set; } 
    [DisplayName("Provider site")] 
    public virtual Hospital SourceSite { get; set; } 

    [DisplayName("Provider person")] 
    public int? SourcePersonId { get; set; } 
    [DisplayName("Provider person")] 
    public virtual Person SourcePerson { get; set; } 

    [DisplayName("Study")] 
    public int StudyId { get; set; } 
    [DisplayName("Study")] 
    public virtual Study Study { get; set; } 

    [DisplayName("Start date")] 
    public virtual PartialDate StartDate { get; set; } 
    [DisplayName("End date")] 
    public virtual PartialDate EndDate { get; set; } 

    public int? RegInvestigatorFormId { get; set; } 
    public PartialDate AuthorizationDate { get; set; } 
    public bool IsNationalCoordinator { get; set; } 

    [DisplayName("Role")] 
    public int RoleId { get; set; } 
    [DisplayName("Role")] 
    public virtual ParticipatingServiceCLI Role { get; set; } 

    [DisplayName("Affiliation type")] 
    public int? AffiliationId { get; set; } 
    public virtual AffiliationCLI Affiliation { get; set; } 

    public bool IsFromActivePersonSite 
    { 
     get 
     { 
      foreach (PersonSite personSite in SourcePerson.PersonSites.ToList().OrderByDescending(ps => ps.StartDate.Date)) 
      { 
       if (personSite.SiteId == SourceSiteId) 
       { 
        return personSite.IsActive(); 
       } 
      } 
      return false; 
     } 
    } 

    public bool IsFromSecondarySite 
    { 
     get 
     { 
      foreach (PersonSite personSite in SourcePerson.PersonSites.ToList().OrderByDescending(ps => ps.StartDate.Date)) 
      { 
       if (personSite.SiteId == SourceSiteId) 
       { 
        return personSite.RelationType.StringId.Equals("Secondary"); 
       } 
      } 
      return false; 
     } 
    } 

    public override bool IsActive() 
    { 
     return !this.IsDeleted && this.SourcePerson != null && this.Study != null && this.TargetSite != null && this.SourcePerson.IsActive() && this.TargetSite.IsActive() && (this.EndDate == null || this.EndDate.Date == null || this.EndDate.Date > DateTime.Now); 
    } 
} 

Repository код:

public virtual T Update(T obj) 
    { 
     System.Data.Entity.Infrastructure.DbEntityEntry<T> dbEntry = this.Context.Entry<T>(obj); 
     System.Data.Entity.Infrastructure.DbPropertyValues x = dbEntry.GetDatabaseValues(); 
     int optimisticValue = x.GetValue<int>("OptimisticVersion"); 
     if ((int)this.Context.Entry<T>(obj).GetDatabaseValues()["OptimisticVersion"] == obj.OptimisticVersion) 
     { 
      obj.OptimisticVersion++; 
      obj.LastModificationDate = DateTime.Now; 
      this.Context.Entry<T>(obj).State = EntityState.Modified; 
      this.Context.SaveChanges(); 
      return obj; 
     } 
     throw new DBConcurrencyException("The selected item is obsolete !"); 
    } 

Проблема:

Я использую общие менеджеров и общие репозитории с CRUD операций (DRY). Проблема в том, что при попытке сохранить объект (только один тип решения вызывает эту проблему), он работает хорошо при первом обновлении. Затем попытка обновления одного и того же объекта снова вызывает NullReferenceException на GetDatabaseValues(). Я попытался разделить следующую строку:

(int)this.Context.Entry<T>(obj).GetDatabaseValues()["OptimisticVersion"] == obj.OptimisticVersion 

в нескольких строк:

System.Data.Entity.Infrastructure.DbEntityEntry<T> dbEntry = this.Context.Entry<T>(obj); 
System.Data.Entity.Infrastructure.DbPropertyValues x = dbEntry.GetDatabaseValues(); 
int optimisticValue = x.GetValue<int>("OptimisticVersion"); 

ли кто-нибудь какие-либо идеи, почему это может захватить базу данных ценят в первый раз и бросить исключение на следующих вызовах?

Вот трассировки стека:

System.Data.Objects.EntityEntry.DetectChangesInComplexType(StateManagerMemberMetadata topLevelMember, StateManagerMemberMetadata complexMember, Object complexValue, Object oldComplexValue) 
at System.Data.Objects.EntityEntry.DetectChangesInProperties(Boolean detectOnlyComplexProperties) 
at System.Data.Objects.EntityEntry.InternalGetOriginalValues(Boolean readOnly) 
at System.Data.Objects.EntityEntry.GetUpdatableOriginalValues() 
at System.Data.Entity.Internal.StateEntryAdapter.GetUpdatableOriginalValues() 
at System.Data.Entity.Internal.InternalEntityEntry.get_OriginalValues() 
at System.Data.Entity.Internal.InternalEntityEntry.GetDatabaseValues() 
at System.Data.Entity.Infrastructure.DbEntityEntry`1.GetDatabaseValues() 
at EORTC.BASE.DAL.EORTCBaseRep`1.Update(T obj) in  C:\Projects\_Prisma\EORTC.BASE.DAL\EORTCBaseRep.cs:line 121 
at EORTC.BASE.BLL.EORTCBaseManager`1.Update(T obj, Boolean validate) in C:\Projects\_Prisma\EORTC.BASE.BLL\EORTCBaseManager.cs:line 58 
at Prisma.BLL.ParticipatingServiceManager.Update(ParticipatingService obj, Boolean validate) in C:\Projects\_Prisma\Prisma.BLL\Managers\Service\ParticipatingServiceManager.cs:line 96 
at Prisma.Web.Controllers.ParticipatingServiceController.Edit(Int32 id, FormCollection collection) in C:\Projects\_Prisma\Prisma.Web\Controllers\Service\ParticipatingServiceController.cs:line 172 
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__DisplayClass15.<InvokeActionMethodWithFilters>b__12() 
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() 
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) 
at System.Web.Mvc.Controller.ExecuteCore() 
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) 
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5() 
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() 
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) 
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End() 
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d() 
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) 
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) 
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) 
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) 
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 
+0

Не могли бы вы указать, какая именно строка запрашивает исключение? – c0dem0nkey

+0

Что такое стек вызовов исключения? – rhughes

+0

Точная строка, которая запрашивает исключение: System.Data.Entity.Infrastructure.DbPropertyValues ​​x = dbEntry.GetDatabaseValues ​​(); След стека добавлен – Whoami

ответ

1

Не могли бы вы использовать проставлены в вашей модели и базы данных таблицы, чтобы отслеживать эти значения?

[Timestamp] 
    public Byte[] Timestamp { get; set; } 
+0

Это не ответ; вы должны использовать комментарии (когда у вас будет достаточно репутации) для этого –

+0

Да, я сожалею об этом, но раньше я не мог публиковать комментарии (я не знаю почему). Я просто попытался помочь –

+0

Да, когда мы пытались использовать OptimisticLock, предоставленный EF, он не смог создать базу данных (без ошибок). Вот почему мы их не использовали (мы не использовали миграции). Но он работает сейчас. Благодарю. – Whoami