public static EntityEntry <TEntity> GetEntityEntry <TEntity>([NotNull] this DbContext @this, TEntity entity, out bool existBefore) where TEntity : class { var type = typeof(TEntity); var entityType = @this.Model.FindEntityType(type); var keysGetter = entityType.FindPrimaryKey().Properties .Select(x => x.PropertyInfo.GetValueGetter <TEntity>()) .ToArray(); var keyValues = keysGetter .Select(x => x.Invoke(entity)) .ToArray(); var originalEntity = @this.Set <TEntity>().Local .FirstOrDefault(x => EFCoreUtil.GetEntityKeyValues(keysGetter, x).SequenceEqual(keyValues)); EntityEntry <TEntity> entityEntry; if (null == originalEntity) { existBefore = false; entityEntry = @this.Attach(entity); } else { existBefore = true; entityEntry = @this.Entry(originalEntity); entityEntry.CurrentValues.SetValues(entity); } return(entityEntry); }
public async Task It_throws_object_disposed_exception(bool async) { var context = new DbContext(new DbContextOptions <DbContext>()); if (async) { await context.DisposeAsync(); } else { context.Dispose(); } // methods (tests all paths) Assert.Throws <ObjectDisposedException>(() => context.Add(new object())); Assert.Throws <ObjectDisposedException>(() => context.Find(typeof(Random), 77)); Assert.Throws <ObjectDisposedException>(() => context.Attach(new object())); Assert.Throws <ObjectDisposedException>(() => context.Update(new object())); Assert.Throws <ObjectDisposedException>(() => context.Remove(new object())); Assert.Throws <ObjectDisposedException>(() => context.SaveChanges()); await Assert.ThrowsAsync <ObjectDisposedException>(() => context.SaveChangesAsync()); await Assert.ThrowsAsync <ObjectDisposedException>(() => context.AddAsync(new object()).AsTask()); await Assert.ThrowsAsync <ObjectDisposedException>(() => context.FindAsync(typeof(Random), 77).AsTask()); var methodCount = typeof(DbContext).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Count(); var expectedMethodCount = 43; Assert.True( methodCount == expectedMethodCount, userMessage: $"Expected {expectedMethodCount} methods on DbContext but found {methodCount}. " + "Update test to ensure all methods throw ObjectDisposedException after dispose."); // getters Assert.Throws <ObjectDisposedException>(() => context.ChangeTracker); Assert.Throws <ObjectDisposedException>(() => context.Model); var expectedProperties = new List <string> { nameof(DbContext.ChangeTracker), nameof(DbContext.ContextId), // By-design, does not throw for disposed context nameof(DbContext.Database), nameof(DbContext.Model) }; Assert.True( expectedProperties.SequenceEqual( typeof(DbContext) .GetProperties() .Select(p => p.Name) .OrderBy(s => s) .ToList()), userMessage: "Unexpected properties on DbContext. " + "Update test to ensure all getters throw ObjectDisposedException after dispose."); Assert.Throws <ObjectDisposedException>(() => ((IInfrastructure <IServiceProvider>)context).Instance); }
public virtual EntityEntry <TEntity> Attach <TEntity>(TEntity entity) where TEntity : class => _dbContext.Attach(entity);