Clone object since EF 6, null reference exception
I am trying to clone an entity (EF 6.x first, code) using the technique here: Entity Framework 5 deep copy / clone object
However, I am getting a strange NullReference exception when trying to add a cloned ticket to the DbSet:
var clonedTicket = _context.Tickets
.AsNoTracking()
.Include(o => o.Lines.Select(l => l.Serials))
.Include(o => o.Payments.Select(p => p.PayCodeInfo))
.SingleOrDefault(o => o.TicketId == ticketId);
clonedTicket.TicketId = _context.Tickets.Max(o => o.TicketId) + 1;
foreach (var line in clonedTicket.Lines)
line.TicketId = clonedTicket.TicketId;
foreach (var payment in clonedTicket.Payments)
payment.TicketId = clonedTicket.TicketId;
_context.Tickets.Add(clonedTicket); <---- System.NullReferenceException
_context.SaveChanges();
The exception is _context.Tickets.Add (clonedTicket).
clonedTicket looks perfectly fine, nothing is null that shouldn't be. Of course, both _context and Tickets (DbSet) are not zero.
Here's the complete exception:
System.NullReferenceException was unhandled by user code
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.MarkForeignKeyPropertiesModified()
at System.Data.Entity.Core.Objects.DataClasses.EntityReference.AddToNavigationPropertyIfCompatible(RelatedEnd otherRelatedEnd)
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Entity.Core.Objects.DataClasses.RelationshipManager.AddRelatedEntitiesToObjectStateManager(Boolean doAttach)
at System.Data.Entity.Core.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
at System.Data.Entity.Internal.Linq.InternalSet`1.<>c__DisplayClassd.<Add>b__c()
at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
at System.Data.Entity.DbSet`1.Add(TEntity entity)
at TheRepo.CreateCloneFromTicket(Int32 ticketId, String clientIp) in c:\...\TheRepo.cs:line 23
at TheController.CreateReturn(Int32 ticketId) in c:\...\TheController.cs:line 232
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
InnerException:
What am I missing here?
source to share
I got this job. The trick was to set ProxyCreationEnabled = false before getting the object:
_context.Configuration.ProxyCreationEnabled = false;
var returnTicket = _context.Tickets
.AsNoTracking()
.Include(o => o.Lines.Select(l => l.Serials))
.Include(o => o.Payments)
.SingleOrDefault(o => o.TicketId == ticketId);
_context.Configuration.ProxyCreationEnabled = true;
I can't say that I fully understand why this is, but my guess is that it has to do with the lazy loading that EF does when ProxyCreation is enabled (which I don't need / need here, since I'm loading related objects explicitly).
source to share