public void TestIdentityInLargeBatch() { _app = new IdentityTestsEntityApp(); Startup.ActivateApp(_app); // For SQLite objects are not dropped (FK problems), so we need to instead delete all data if (Startup.ServerType == Data.Driver.DbServerType.SQLite) { DeleteAllData(); } var sqlDialect = _app.GetDefaultDatabase().DbModel.Driver.SqlDialect; var saveParamCount = sqlDialect.MaxParamCount; sqlDialect.MaxParamCount = 20; //to cause update batch split into multiple commands var session = _app.OpenSession(); // add 50 owners, then 200 cars with random owners // our goal is to create update set with inserts of linked entities with identity pk/fk // we test how identity values are carried between commands (from IPerson.Id to ICar.OwnerId) var owners = new List <IPerson>(); var rand = new Random(); for (int i = 0; i < 50; i++) { var owner = session.NewEntity <IPerson>(); owner.Name = "Owner" + i; owners.Add(owner); } for (int i = 0; i < 100; i++) { var car = session.NewEntity <ICar>(); car.Model = "Model" + i; car.Owner = owners[rand.Next(owners.Count)]; } try { session.SaveChanges(); //we just test that it succeeds } finally { //revert max param count back to normal - to avoid disturbing other tests sqlDialect.MaxParamCount = saveParamCount; } }
public static void DeleteAllData(EntityApp app, IEnumerable <Type> inEntities = null, IEnumerable <Type> exceptEntities = null, IList <string> extraTablesToDelete = null) { Util.Check(app.Status == EntityAppStatus.Connected, "EntityApp must be connected to database."); var db = app.GetDefaultDatabase(); var dbSettings = db.Settings; var driver = dbSettings.Driver; if (inEntities == null) { inEntities = app.GetAllEntityTypes(); } var typesToClear = new HashSet <Type>(inEntities); if (exceptEntities != null) { typesToClear.ExceptWith(exceptEntities); } // get existing tables; in unit tests it might happen that when we delete all for table that does not exist yet var modelLoader = driver.CreateDbModelLoader(dbSettings, app.ActivationLog); var schemas = app.Areas.Select(a => a.Name).ToList(); modelLoader.SetSchemasSubset(schemas); var oldModel = modelLoader.LoadModel(); var oldtableNames = new HashSet <string>(oldModel.Tables.Select(t => t.FullName), StringComparer.OrdinalIgnoreCase); //Figure out table/entity list and sort it var modelInfo = app.Model; var entList = new List <EntityInfo>(); foreach (var entType in typesToClear) { var entityInfo = modelInfo.GetEntityInfo(entType); if (entityInfo == null) { continue; } entList.Add(entityInfo); } //sort in topological order entList.Sort((x, y) => x.TopologicalIndex.CompareTo(y.TopologicalIndex)); // delete all one-by-one var conn = driver.CreateConnection(dbSettings.ConnectionString); conn.Open(); var cmd = conn.CreateCommand(); cmd.Transaction = conn.BeginTransaction(); try { if (extraTablesToDelete != null) { foreach (var extraTable in extraTablesToDelete) { if (oldtableNames.Contains(extraTable)) { ExecuteDelete(driver, cmd, extraTable); } } } foreach (var entityInfo in entList) { var table = db.DbModel.LookupDbObject <DbTableInfo>(entityInfo); if (table == null) { continue; } if (!oldtableNames.Contains(table.FullName)) { continue; } ExecuteDelete(driver, cmd, table.FullName); } } finally { cmd.Transaction.Commit(); conn.Close(); } }