public void Optimistic_concurrency_error_attempting_to_delete_previously_modified_entity_when_using_property_as_concurrency_token() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { using (var context2 = new GearsOfWarContext()) { var baird = context.Gears.Where(g => g.Nickname == "Baird").Single(); var baird2 = context2.Gears.Where(g => g.Nickname == "Baird").Single(); baird.Rank = MilitaryRank.Lieutenant; context.SaveChanges(); context2.Gears.Remove(baird2); Assert.Throws <DbUpdateException>(() => context2.SaveChanges()).InnerException .ValidateMessage(typeof(DbContext).Assembly(), "Update_ConcurrencyError", null); } } } }); }
public void Optimisic_concurrency_error_when_deleting_previously_modified_reference() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { using (var context2 = new GearsOfWarContext()) { var jacinto = context.Cities.Where(c => c.Name == "Jacinto").Single(); var cole = context.Gears.Where(g => g.Nickname == "Cole Train").Include(g => g.CityOfBirth).Single(); var cole2 = context2.Gears.Where(g => g.Nickname == "Cole Train").Include(g => g.CityOfBirth).Single(); cole.CityOfBirth = jacinto; context.SaveChanges(); cole2.CityOfBirth = null; Assert.Throws <DbUpdateException>(() => context2.SaveChanges()) .InnerException.ValidateMessage(typeof(DbContext).Assembly(), "Update_ConcurrencyError", null); } } } }); }
public void Optimistic_concurrency_error_on_property_update_previously_modified_entity_when_using_timestamp() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { using (var context2 = new GearsOfWarContext()) { var gnasher = context.Weapons.Where(w => w.Name == "Gnasher").Single(); var gnasher2 = context2.Weapons.Where(w => w.Name == "Gnasher").Single(); gnasher.Name = "Gnasher Mk 2"; context.SaveChanges(); gnasher2.Name = "Sawed-off"; Assert.Throws <DbUpdateConcurrencyException>(() => context2.SaveChanges()) .ValidateMessage(typeof(DbContext).Assembly(), "Update_ConcurrencyError", null); } } } }); }
public void Optimistic_concurrency_error_attempting_to_modify_previously_deleted_entity_when_using_timestamp() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { using (var context2 = new GearsOfWarContext()) { var troika = new HeavyWeapon { Name = "Troika", Overheats = true, }; context.Weapons.Add(troika); context.SaveChanges(); var troika2 = context2.Weapons.OfType <HeavyWeapon>().Where(w => w.Name == "Troika").Single(); context.Weapons.Remove(troika); context.SaveChanges(); troika2.Overheats = false; Assert.Throws <DbUpdateConcurrencyException>(() => context2.SaveChanges()) .ValidateMessage(typeof(DbContext).Assembly(), "Update_ConcurrencyError", null); } } } }); }
public void Modifying_non_generated_key_throws() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { var squad = new Squad { Id = 10, Name = "Lima", }; context.Squads.Add(squad); context.SaveChanges(); squad.Id = 20; Assert.Throws <InvalidOperationException>(() => context.SaveChanges()) .ValidateMessage(typeof(DbContext).Assembly(), "ObjectStateEntry_CannotModifyKeyProperty", null, "Id"); } } }); }
public void Modifying_identity_non_key_throws() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { var squad = new Squad { Id = 10, Name = "Lima", }; context.Squads.Add(squad); context.SaveChanges(); var squadInternalNumber = squad.InternalNumber; squad.InternalNumber = squadInternalNumber + 1; Assert.Throws <DbUpdateException>(() => context.SaveChanges()) .InnerException.InnerException.ValidateMessage( typeof(DbContext).Assembly(), "Update_ModifyingIdentityColumn", null, "Identity", "InternalNumber", "CodeFirstDatabaseSchema.Squad"); } } }); }
public void Verify_that_deletes_precede_inserts() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { var squad1 = new Squad { Id = 3, Name = "Alpha", }; context.Squads.Add(squad1); context.SaveChanges(); var squad2 = new Squad { Id = 3, Name = "Bravo", }; context.Squads.Add(squad2); context.Squads.Remove(squad1); context.SaveChanges(); Assert.Equal( "Bravo", context.Squads.Where(o => o.Id == 3).Select(s => s.Name).Single()); } } }); }
public void Fixup_of_two_relationships_that_share_a_key_results_in_correct_removal_of_dangling_foreign_keys() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (var context = new Context2172()) { context.Database.Initialize(force: false); } using (new TransactionScope()) { using (var context = new Context2172()) { var user = context.Users.Add(new User2172 { Id = 1 }); context.SaveChanges(); var message = context.Messages.Add(new Message2172 { Id = 1, CreatedById = 1, ModifiedById = 1 }); context.SaveChanges(); context.Messages.Remove(message); context.SaveChanges(); context.Entry(user).State = EntityState.Detached; Assert.NotNull(context.Users.First(u => u.Id == user.Id)); } } }); }
public void Read_and_write_using_AdvancedPatternsModelFirst_created_from_T4_template() { var building18 = CreateBuilding(); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new AdvancedPatternsModelFirstContext()) { context.Buildings.Add(building18); var foundBuilding = context.Buildings.Find(new Guid(Building18Id)); Assert.Equal("Building 18", foundBuilding.Name); context.SaveChanges(); } using (var context = new AdvancedPatternsModelFirstContext()) { var foundBuilding = context.Buildings.Find(new Guid(Building18Id)); Assert.Equal("Building 18", foundBuilding.Name); Assert.Equal(3, context.Entry(foundBuilding).Collection(b => b.Offices).Query().Count()); var arthursOffice = context.Offices.Single(o => o.Number == "1/1125"); Assert.Same(foundBuilding, arthursOffice.GetBuilding()); } } }); }
public void Update_resulting_in_data_truncation_throws_exception() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { var cogTagNoteMaxLength = 40; var cogTag = new CogTag { Id = Guid.NewGuid(), Note = new string('A', cogTagNoteMaxLength), }; context.Tags.Add(cogTag); context.SaveChanges(); cogTag.Note = new string('A', cogTagNoteMaxLength + 1); Assert.Throws <DbUpdateException>(() => context.SaveChanges()); } } }); }
public void Read_and_write_using_MonsterModel_created_from_T4_template() { int orderId; int?customerId; ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new MonsterModel()) { var entry = context.Entry(CreateOrder()); entry.State = EntityState.Added; context.SaveChanges(); orderId = entry.Entity.OrderId; customerId = entry.Entity.CustomerId; } using (var context = new MonsterModel()) { var order = context.Order.Include(o => o.Customer).Single(o => o.CustomerId == customerId); Assert.Equal(orderId, order.OrderId); Assert.True(order.Customer.Orders.Contains(order)); } } }); }
public void Update_Many_to_Many_relationship_using_stored_procedures() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { List <int?> usedWeaponIds; List <int?> unusedWeaponIds; using (var context = new GearsOfWarStoredProceduresContext()) { var gear = context.Gears.OrderBy(g => g.Nickname).ThenBy(g => g.Squad).First(); usedWeaponIds = gear.Weapons.Select(w => w.Id).ToList(); var unusedWeapons = context.Weapons .Where(w => !usedWeaponIds.Contains(w.Id)).ToList(); unusedWeaponIds = unusedWeapons.Select(w => w.Id).ToList(); gear.Weapons = unusedWeapons; context.SaveChanges(); } using (var context = new GearsOfWarStoredProceduresContext()) { var gear = context.Gears.OrderBy(g => g.Nickname).ThenBy(g => g.Squad).First(); Assert.True(gear.Weapons.All(w => unusedWeaponIds.Contains(w.Id))); } } }); }
public void Delete_GearsOfWar_entities_using_stored_procedures() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarStoredProceduresContext()) { var cities = context.Cities.ToList(); var gears = context.Gears.ToList(); var squads = context.Squads.ToList(); var tags = context.Tags.ToList(); var weapons = context.Weapons.ToList(); context.Cities.RemoveRange(cities); context.Gears.RemoveRange(gears); context.Squads.RemoveRange(squads); context.Tags.RemoveRange(tags); context.Weapons.RemoveRange(weapons); context.SaveChanges(); } using (var context = new GearsOfWarStoredProceduresContext()) { Assert.Equal(0, context.Cities.Count()); Assert.Equal(0, context.Gears.Count()); Assert.Equal(0, context.Squads.Count()); Assert.Equal(0, context.Tags.Count()); Assert.Equal(0, context.Weapons.Count()); } } }); }
public void Verify_insert_update_delete_for_guid_identity_column() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GuidIdentityColumnContext()) { var customer = context.Customers.Single(); var orders = customer.Orders.ToList(); orders[0].Name = "Changed Name"; context.Orders.Remove(orders[1]); context.SaveChanges(); } using (var context = new GuidIdentityColumnContext()) { var customer = context.Customers.Single(); var orders = customer.Orders; Assert.Equal(1, orders.Count()); Assert.Equal("Changed Name", orders.Single().Name); } } }); }
public void Modifying_identity_generated_key_throws() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { var tag = new CogTag { Id = Guid.NewGuid(), Note = "Some Note", }; context.Tags.Add(tag); context.SaveChanges(); tag.Id = Guid.NewGuid(); Assert.Throws <InvalidOperationException>(() => context.SaveChanges()) .ValidateMessage(typeof(DbContext).Assembly(), "ObjectStateEntry_CannotModifyKeyProperty", null, "Id"); } } }); }
public void Multiple_entities_in_exception_from_update_pipeline_can_be_handled() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new AdvancedPatternsMasterContext()) { // Create two entities which both have dependencies on each other // to force a dependency ordering exception from the update pipeline. var building = new Building { BuildingId = new Guid("14C62AB6-A49C-40BD-BD5C-D374E070D3D7"), Name = "Building 18", Value = 1m, PrincipalMailRoomId = -1, Address = new Address { Street = "100 Work St", City = "Redmond", State = "WA", ZipCode = "98052", SiteInfo = new SiteInfo { Zone = 1, Environment = "Clean" } }, }; var mailRoom = new MailRoom { id = (int)building.PrincipalMailRoomId, BuildingId = building.BuildingId }; context.Buildings.Add(building); context.Set <MailRoom>().Add(mailRoom); try { context.SaveChanges(); Assert.True(false); } catch (DbUpdateException ex) { Assert.IsType <UpdateException>(ex.InnerException); var entries = ex.Entries.ToList(); Assert.Equal(2, entries.Count()); Assert.True(entries.Any(e => ReferenceEquals(e.Entity, building))); Assert.True(entries.Any(e => ReferenceEquals(e.Entity, mailRoom))); } } } }); }
public void Insert_update_delete_entity_with_spatial_property() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new GearsOfWarContext()) { var GeographySrid = 4326; var halvoBay = new City { Name = "Halvo Bay", Location = DbGeography.FromText("POINT(10 10)", GeographySrid), }; context.Cities.Add(halvoBay); context.SaveChanges(); Assert.True(context.Cities.Where(c => c.Name == "Halvo Bay").Any()); halvoBay.Location = DbGeography.FromText("POINT(20 20)", GeographySrid); context.SaveChanges(); var halvoBaysNewLocation = context.Cities.Where(g => g.Name == "Halvo Bay").Select(g => g.Location).Single(); Assert.True(halvoBaysNewLocation.SpatialEquals(DbGeography.FromText("POINT(20 20)", GeographySrid))); context.Cities.Remove(halvoBay); context.SaveChanges(); Assert.False(context.Cities.Where(g => g.Name == "Halvo Bay").Any()); } } }); }
public void Can_insert_update_and_delete_when_tpt_inheritance() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = CreateContext()) { var customer = new SpecialCustomer(); Assert.Equal(0, context.Set <SpecialCustomer>().Count()); // Insert context.Set <SpecialCustomer>().Add(customer); context.SaveChanges(); Assert.Equal(1, context.Set <SpecialCustomer>().Count()); // Update customer.Points = 1; context.SaveChanges(); Assert.Equal(1, context.Set <SpecialCustomer>().Select(c => c.Points).First()); // Delete context.Set <SpecialCustomer>().Remove(customer); context.SaveChanges(); Assert.Equal(0, context.Set <SpecialCustomer>().Count()); } } }); }
public void Generic_DbEntityEntry_State_calls_DetectChanges_for_detached_unchanged_entities() { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (var context = new SimpleModelContext()) { using (new TransactionScope()) { var entry = context.Entry(new Product()); context.Products.Add(entry.Entity); context.SaveChanges(); // Ensure that the entity doesn't have a change tracking proxy Assert.Equal( entry.Entity.GetType(), ObjectContext.GetObjectType(entry.Entity.GetType())); // DetectChanges is called the first time the state is queried for a detached entity Assert.Equal(EntityState.Unchanged, entry.State); entry.Entity.Name = "foo"; Assert.Equal(EntityState.Unchanged, entry.State); } } }); }
public void Explicit_rollback_can_be_used_to_rollback_a_transaction() { EnsureDatabaseInitialized(() => new SimpleModelContext()); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (var tx = new TransactionScope()) { using (var context = new SimpleModelContext()) { var product = new Product { Name = "BestTea" }; context.Products.Add(product); context.SaveChanges(); Assert.Equal(1, GetTransactionCount(context.Database.Connection)); Assert.True(context.Products.Where(p => p.Name == "BestTea").AsNoTracking().Any()); // Rollback System Transaction tx.Dispose(); Assert.False(context.Products.Where(p => p.Name == "BestTea").AsNoTracking().Any()); } } }); }
public void Code_First_can_use_nested_types() { using (var nested = new NestedContext()) { var cheese = nested.Cheeses.Single(); Assert.Equal("Swiss", cheese.Name); Assert.Equal(Maturity.Todler, cheese.Info.Maturity); Assert.Equal(16, cheese.Info.Image.Length); Assert.Equal(new[] { "Ketchup", "Mustard" }, cheese.Pickles.Select(p => p.Name).OrderBy(n => n)); cheese.Pickles.Add( new Pickle { Name = "Not Pickles" }); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (nested.Database.BeginTransaction()) { nested.SaveChanges(); Assert.Equal( new[] { "Ketchup", "Mustard", "Not Pickles" }, nested.Pickles.AsNoTracking().Select(p => p.Name).OrderBy(n => n)); } }); } }
private static void InsertAndUpdateWithDecimals( decimal insertValue, decimal insertExpected, decimal updateValue, decimal updateExpected) { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new ArubaContext()) { // Insert var allTypes = context.AllTypes.Add(CreateArubaAllTypes(insertValue)); context.SaveChanges(); ValidateSavedValues(context, allTypes, insertExpected); // Update UpdateArubaAllTypes(allTypes, updateValue); context.SaveChanges(); ValidateSavedValues(context, allTypes, updateExpected); } } }); }
public void Explicit_rollback_on_a_local_transaction_can_be_used_to_rollback_a_transaction() { EnsureDatabaseInitialized(() => new SimpleModelContext()); using (var context = new SimpleModelContext()) { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { // Begin a local transaction var transaction = BeginLocalTransaction(context); var product = new Product { Name = "New Tea" }; context.Products.Add(product); context.SaveChanges(); Assert.True(context.Products.Where(p => p.Name == "New Tea").AsNoTracking().Any()); // Rollback local transaction transaction.Rollback(); CloseEntityConnection(context); Assert.False(context.Products.Where(p => p.Name == "New Tea").AsNoTracking().Any()); }); } }
SqlServer_Database_can_be_created_with_columns_that_implicitly_total_more_that_8060_bytes_and_data_longer_than_8060_can_be_inserted () { EnsureDatabaseInitialized(() => new ModelWithWideProperties()); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new ModelWithWideProperties()) { var entity = new EntityWithImplicitWideProperties { Property1 = new String('1', 1000), Property2 = new String('2', 1000), Property3 = new String('3', 1000), Property4 = new String('4', 1000), }; context.ImplicitlyWide.Add(entity); context.SaveChanges(); entity.Property1 = new String('A', 4000); entity.Property2 = new String('B', 4000); context.SaveChanges(); } } }); }
public void Scenario_Relate_using_FK() { EnsureDatabaseInitialized(() => new SimpleModelContext()); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new SimpleModelContext()) { var product = new Product { Name = "Bovril", CategoryId = "Foods" }; context.Products.Add(product); context.SaveChanges(); // Scenario ends; simple validation of final state follows Assert.NotNull(product); Assert.Equal(EntityState.Unchanged, GetStateEntry(context, product).State); Assert.Equal("Foods", product.CategoryId); } } }); }
/// <summary> /// Drops the database that would be used for the context. Usually used to avoid errors during initialization. /// </summary> /// <param name="createContext"> A func to create the context. </param> protected static void DropDatabase(Func <DbContext> createContext) { using (var context = createContext()) { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => context.Database.Delete()); } }
/// <summary> /// Ensures the database for the context is created and seeded. This is typically used /// when a test is going to use a transaction to ensure that the DDL happens outside of /// the transaction. /// </summary> /// <param name="createContext"> A func to create the context. </param> protected static void EnsureDatabaseInitialized(Func <DbContext> createContext) { using (var context = createContext()) { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => context.Database.Initialize(force: false)); } }
public void Scenario_Using_two_databases() { EnsureDatabaseInitialized(() => new LoginsContext()); EnsureDatabaseInitialized(() => new SimpleModelContext()); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new LoginsContext()) { var login = new Login { Id = Guid.NewGuid(), Username = "******" }; context.Logins.Add(login); context.SaveChanges(); // Scenario ends; simple validation of final state follows Assert.Same(login, context.Logins.Find(login.Id)); Assert.Equal(EntityState.Unchanged, GetStateEntry(context, login).State); } } }); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (new TransactionScope()) { using (var context = new SimpleModelContext()) { var category = new Category { Id = "Books" }; var product = new Product { Name = "The Unbearable Lightness of Being", Category = category }; context.Products.Add(product); context.SaveChanges(); // Scenario ends; simple validation of final state follows Assert.Equal(EntityState.Unchanged, GetStateEntry(context, product).State); Assert.Equal(EntityState.Unchanged, GetStateEntry(context, category).State); Assert.Equal("Books", product.CategoryId); Assert.Same(category, product.Category); Assert.True(category.Products.Contains(product)); } } }); }
public void CommitFailureHandler_supports_nested_transactions() { MutableResolver.AddResolver <Func <TransactionHandler> >( new TransactionHandlerResolver(() => new CommitFailureHandler(), null, null)); try { using (var context = new BlogContextCommit()) { ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { context.Database.Delete(); Assert.Equal(1, context.Blogs.Count()); }); context.Blogs.Add(new BlogContext.Blog()); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (var transaction = context.Database.BeginTransaction()) { using (var innerContext = new BlogContextCommit()) { using (var innerTransaction = innerContext.Database.BeginTransaction()) { Assert.Equal(1, innerContext.Blogs.Count()); innerContext.Blogs.Add(new BlogContext.Blog()); innerContext.SaveChanges(); innerTransaction.Commit(); } } context.SaveChanges(); transaction.Commit(); } }); } ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (var context = new BlogContextCommit()) { Assert.Equal(3, context.Blogs.Count()); } }); } finally { MutableResolver.ClearResolvers(); } DbDispatchersHelpers.AssertNoInterceptors(); }
public static void DoStuff(BlogContext context) { Blog blog = null; Post post = null; ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { blog = context.Blogs.Single(); Assert.Equal("Half a Unicorn", blog.Title); post = blog.Posts.Single(); Assert.Equal("Wrap it up...", post.Title); }); blog.Posts.Add( new Post { Title = "Throw it away..." }); ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (context.Database.BeginTransaction()) { Assert.Equal(1, context.SaveChanges()); Assert.Equal( new[] { "Throw it away...", "Wrap it up..." }, context.Posts.AsNoTracking().Select(p => p.Title).OrderBy(t => t)); } }); #if !NET40 ExtendedSqlAzureExecutionStrategy.ExecuteNew( () => { using (context.Database.BeginTransaction()) { post.Title = "I'm a logger and I'm okay..."; var saveTask = context.SaveChangesAsync(); saveTask.Wait(); Assert.Equal(1, saveTask.Result); var queryTask = context.Posts .AsNoTracking() .Select(p => p.Title).OrderBy(t => t) .ToListAsync(); queryTask.Wait(); Assert.Equal(new[] { "I'm a logger and I'm okay..." }, queryTask.Result); } }); #endif }