public void TestIdentityColumns() { _app = new IdentityTestsEntityApp(); Startup.DropSchemaObjects("ident"); Startup.ActivateApp(_app); var session = _app.OpenSession(); var john = session.NewEntity <IPerson>(); john.Name = "John S"; var car1 = session.NewEntity <ICar>(); car1.Model = "Beatle"; car1.Owner = john; var car2 = session.NewEntity <ICar>(); car2.Model = "Explorer"; car2.Owner = john; Assert.IsTrue(car1.Id < 0, "Car ID is expected to be <0 before saving."); session.SaveChanges(); //Check that Identity values immediately changed to actual positive values loaded from database Assert.IsTrue(john.Id > 0, "Invalid person ID - expected positive value."); Assert.IsTrue(car1.Id > 0, "Invalid car1 ID - expected positive value."); Assert.IsTrue(car2.Id > 0, "Invalid car2 ID - expected positive value."); //Start new session, load all and check that IDs and relationships are correct session = _app.OpenSession(); john = session.EntitySet <IPerson>().Where(p => p.Name == "John S").Single(); var cars = session.GetEntities <ICar>().ToList(); car1 = cars[0]; car2 = cars[1]; Assert.IsTrue(john.Id > 0 && car1.Id > 0 && car2.Id > 0, "IDs expected to become > 0 after saving."); Assert.IsTrue(car1.Owner == john, "Owner expected to be John"); Assert.IsTrue(car2.Owner == john, "Owner expected to be John"); }//method
public void TestOneToOneRef() { _app = new OneToOneEntityApp(); Startup.DropSchemaObjects("one"); Startup.ActivateApp(_app); var session = _app.OpenSession(); //initial setup session = _app.OpenSession(); var header = session.NewEntity <IDocHeader>(); header.Name = "Doc1"; var det = session.NewEntity <IDocDetails>(); det.Details = "Some details"; det.Header = header; var cm = session.NewEntity <IDocComments>(); cm.Details = det; cm.Comment = "Some comment"; session.SaveChanges(); //test LINQ queries - used to fail var query = session.EntitySet <IDocComments>().Where(dc => dc.Details == det); var cmList = query.ToList(); Assert.IsTrue(cmList.Count == 1, "Expected 1 comment."); //Test can delete method, also used to fail with one-to-one Type[] bt; var canDel = session.CanDeleteEntity(det, out bt); Assert.IsFalse(canDel, "Expected CanDelete = false."); // test [OneToOne] entity // IDocHeader.Details is 'back-ref' property, marked with OneToOne attribute // IDocHeader.Details2 is similar, but we did not create IDocDetails2 record, so it should be null var docId = header.Id; session = _app.OpenSession(); var doc = session.GetEntity <IDocHeader>(docId); var det1 = doc.Details; Assert.IsNotNull(det1, "Expected Details"); var det2 = doc.Details2; Assert.IsNull(det2, "Expected Details2 = null"); //do it again, to check it is correctly cached in record (so it does not blow up) det1 = doc.Details; det2 = doc.Details2; // test using [OneToOne] references in Linq session = _app.OpenSession(); var q2 = session.EntitySet <IDocHeader>().Where(h => h.Details.Details == "Some details"); var docs = q2.ToList(); Assert.AreEqual(1, docs.Count, "Expected Doc header"); } //method
}//method // For SQLite objects are not dropped (FK problems), so we need to instead delete all data // to make sure we start with empty tables private void DeleteAllData() { var session = _app.OpenSession(); session.ExecuteDelete <IUserPost>(session.EntitySet <IUserPost>()); session.ExecuteDelete <IUser>(session.EntitySet <IUser>()); }
public void TestIdentityColumns() { _app = new IdentityTestsEntityApp(); SetupHelper.DropSchemaObjects("ident"); SetupHelper.ActivateApp(_app); var session = _app.OpenSession(); var john = session.NewEntity<IPerson>(); john.Name = "John S"; var car1 = session.NewEntity<ICar>(); car1.Model = "Beatle"; car1.Owner = john; var car2 = session.NewEntity<ICar>(); car2.Model = "Explorer"; car2.Owner = john; Assert.IsTrue(car1.Id < 0, "Car ID is expected to be <0 before saving."); session.SaveChanges(); //Check that Identity values immediately changed to actual positive values loaded from database Assert.IsTrue(john.Id > 0, "Invalid person ID - expected positive value."); Assert.IsTrue(car1.Id > 0, "Invalid car1 ID - expected positive value."); Assert.IsTrue(car2.Id > 0, "Invalid car2 ID - expected positive value."); //Start new session, load all and check that IDs and relationships are correct session = _app.OpenSession(); var persons = session.GetEntities<IPerson>().ToList(); john = persons[0]; var cars = session.GetEntities<ICar>().ToList(); car1 = cars[0]; car2 = cars[1]; Assert.IsTrue(john.Id > 0 && car1.Id > 0 && car2.Id > 0, "IDs expected to become > 0 after saving."); Assert.IsTrue(car1.Owner == john, "Owner expected to be John"); Assert.IsTrue(car2.Owner == john, "Owner expected to be John"); }
public void RunTestIdentityWithSelfRefEntities() { _app = new IdentityTestsEntityApp(); Startup.ActivateApp(_app); //if(Startup.ServerType == Data.Driver.DbServerType.SQLite) DeleteAllData(); var session = _app.OpenSession(); // Create 3-level tree and save it var node1 = session.NewNode("N1"); // level 2 var node11 = session.NewNode("N11", node1); var node12 = session.NewNode("N12", node1); var node13 = session.NewNode("N13", node1); // level 3 var node111 = session.NewNode("N1111", node11); var node112 = session.NewNode("N1112", node11); var node121 = session.NewNode("N1121", node12); var node122 = session.NewNode("N1122", node12); var node131 = session.NewNode("N1131", node13); var node132 = session.NewNode("N1132", node13); DataUtility.RandomizeRecordOrder(session); session.SaveChanges(); // test passed if it executed without exceptions Assert.IsTrue(true, "never happens"); }
public void RunTest(bool batchMode) { _app = new IdentityRefTestEntityApp(); Startup.ActivateApp(_app); //if(Startup.ServerType == Data.Driver.DbServerType.SQLite) DeleteAllData(); // We create session this way to set the batch mode flag var ctx = new OperationContext(_app); IEntitySession session = new EntitySession(ctx, options: batchMode ? EntitySessionOptions.None : EntitySessionOptions.DisableBatchMode); var john = session.NewUser("john"); var post1 = john.NewPost("john post 1", 1); var post2 = john.NewPost("john post 2", 2); var post3 = john.NewPost("john post 3", 3); var ben = session.NewUser("ben"); var post1b = ben.NewPost("ben post 1", 1); var post2b = ben.NewPost("ben post 2", 2); var post3b = ben.NewPost("ben post 3", 3); session.SaveChanges(); //Check that Identity values immediately changed to actual positive values loaded from database Assert.IsTrue(post1.OrderId > 0, "Invalid OrderID - expected positive value."); Assert.IsTrue(post2.OrderId > 0, "Invalid OrderID - expected positive value."); Assert.IsTrue(post3.OrderId > 0, "Invalid OrderID - expected positive value."); //Start new session, load all and check that IDs and relationships are correct session = _app.OpenSession(); var posts = session.EntitySet <IUserPost>().ToList(); foreach (var post in posts) { Assert.IsTrue(post.OrderId > 0); } }//method
public void TestModuleIntegration() { var schema = "usr"; Startup.DropSchemaObjects(schema); //start from scratch // Runs integrated app by Randy _app = new EntityApp(); var area = _app.AddArea(schema); var persModule = new Bob.PersonModule(area); var loginModule = new Alice.LoginModule(area, typeof(IPersonExt)); // Now replace original entities with new interfaces; // Alice's IUserStub is already replaced by Randy's IPersonExt. _app.ReplaceEntity(typeof(Alice.ILogin), typeof(IAppLogin)); _app.ReplaceEntity(typeof(Bob.IPerson), typeof(IPersonExt)); // activate Startup.ActivateApp(_app); //Test the resulting solution var session = _app.OpenSession(); var pers = session.NewEntity <IPersonExt>(); pers.FirstName = "John"; pers.LastName = "Dow"; pers.BirthDate = new DateTime(1970, 5, 1); pers.Gender = Gender.Male; var login = session.NewEntity <IAppLogin>(); var loginId = login.Id; login.User = pers; login.UserName = "******"; login.FriendlyName = "JohnD"; login.PasswordHash = 123; login.EmployeeNumber = "E111"; session.SaveChanges(); //Let's try to login the user we created using Alice's method session = _app.OpenSession(); var johnLogin = Alice.LoginModule.Login(session, "johnd", 123); var cmd = session.GetLastCommand(); Assert.IsNotNull(johnLogin, "Login failed"); } //method
public void TestIdentityColumns(bool batchMode) { _app = new IdentityTestsEntityApp(); Startup.ActivateApp(_app); //if(Startup.ServerType == Data.Driver.DbServerType.SQLite) DeleteAllData(); // We create session this way to set the batch mode flag var ctx = new OperationContext(_app); IEntitySession session = new EntitySession(ctx, options: batchMode ? EntitySessionOptions.None : EntitySessionOptions.DisableBatchMode); var john = session.NewEntity <IPerson>(); john.Name = "John S"; //john.Name = "Джон Ш"; //Russian var car1 = session.NewEntity <ICar>(); car1.Model = "Beatle"; car1.Owner = john; car1.CoOwner = null; var car2 = session.NewEntity <ICar>(); car2.Model = "Explorer"; car2.Owner = john; Assert.IsTrue(car1.Id < 0, "Car ID is expected to be <0 before saving."); session.SaveChanges(); //Check that Identity values immediately changed to actual positive values loaded from database Assert.IsTrue(john.Id > 0, "Invalid person ID - expected positive value."); Assert.IsTrue(car1.Id > 0, "Invalid car1 ID - expected positive value."); Assert.IsTrue(car2.Id > 0, "Invalid car2 ID - expected positive value."); //Start new session, load all and check that IDs and relationships are correct session = _app.OpenSession(); john = session.EntitySet <IPerson>().Where(p => p.Name == "John S").Single(); var cars = session.GetEntities <ICar>().ToList(); car1 = cars[0]; car2 = cars[1]; Assert.IsTrue(john.Id > 0 && car1.Id > 0 && car2.Id > 0, "IDs expected to become > 0 after saving."); Assert.IsTrue(car1.Owner == john, "Owner expected to be John"); Assert.IsTrue(car2.Owner == john, "Owner expected to be John"); // Testing list.Contains with long (bigint) values, used to fail for SQL Server var longArray = new long[] { long.MaxValue - 10, long.MaxValue - 9, long.MaxValue - 8 }; // we just test that this does not blow up var someCars = session.EntitySet <ICar>().Where(c => longArray.Contains(c.Id)).ToList(); var sql = session.GetLastCommand().CommandText; Assert.AreEqual(0, someCars.Count); }//method
// For SQLite objects are not dropped (FK problems), so we need to instead delete all data // to make sure we start with empty tables private void DeleteAllData() { var session = _app.OpenSession(); var allCars = session.GetEntities <ICar>(take: 100).ToList(); foreach (var c in allCars) { session.DeleteEntity(c); } session.SaveChanges(); var allP = session.GetEntities <IPerson>(take: 100).ToList(); foreach (var p in allP) { session.DeleteEntity(p); } session.SaveChanges(); }
public void TestIdentityInLargeBatch() { _app = new IdentityTestsEntityApp(); Startup.DropSchemaObjects("ident"); Startup.ActivateApp(_app); var saveParamCount = Startup.Driver.MaxParamCount; Startup.Driver.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 cars = new List <ICar>(); 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)]; cars.Add(car); } try { session.SaveChanges(); //we just test that it succeeds } finally { //revert max param count back to normal - to avoid disturbing other tests Startup.Driver.MaxParamCount = saveParamCount; } // check that all FKs had been set (changed from negative to real positive values) foreach (var car in cars) { var ownerId = (int)EntityHelper.GetProperty(car, "Owner_id"); Assert.IsTrue(ownerId > 0, "Expected OwnerId > 0"); } }
public void TestIdentityColumns(bool batchMode) { _app = new IdentityTestsEntityApp(); Startup.ActivateApp(_app); //if(Startup.ServerType == Data.Driver.DbServerType.SQLite) DeleteAllData(); // We create session this way to set the batch mode flag var ctx = new OperationContext(_app); IEntitySession session = new EntitySession(ctx, options: batchMode ? EntitySessionOptions.None : EntitySessionOptions.DisableBatchMode); var john = session.NewEntity <IPerson>(); john.Name = "John S"; var car1 = session.NewEntity <ICar>(); car1.Model = "Beatle"; car1.Owner = john; car1.CoOwner = null; var car2 = session.NewEntity <ICar>(); car2.Model = "Explorer"; car2.Owner = john; Assert.IsTrue(car1.Id < 0, "Car ID is expected to be <0 before saving."); session.SaveChanges(); //Check that Identity values immediately changed to actual positive values loaded from database Assert.IsTrue(john.Id > 0, "Invalid person ID - expected positive value."); Assert.IsTrue(car1.Id > 0, "Invalid car1 ID - expected positive value."); Assert.IsTrue(car2.Id > 0, "Invalid car2 ID - expected positive value."); //Start new session, load all and check that IDs and relationships are correct session = _app.OpenSession(); john = session.EntitySet <IPerson>().Where(p => p.Name == "John S").Single(); var cars = session.GetEntities <ICar>().ToList(); car1 = cars[0]; car2 = cars[1]; Assert.IsTrue(john.Id > 0 && car1.Id > 0 && car2.Id > 0, "IDs expected to become > 0 after saving."); Assert.IsTrue(car1.Owner == john, "Owner expected to be John"); Assert.IsTrue(car2.Owner == john, "Owner expected to be John"); }//method
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 void TestLinqPrecedence() { var session = _app.OpenSession(); var data = session.EntitySet <IArithmData>(); // Precedence tests // test * vs + object result = data.Where(d => d.I1 + d.I2 * d.I3 + d.I4 > 0).ToList(); var where = GetLastWhere(session); Assert.AreEqual("I1+I2*I3+I4>0", where, "WHERE clause mismatch."); // Other precedence cases result = data.Where(d => d.I1 + d.I2 * (d.I3 + d.I4) > 0).ToList(); where = GetLastWhere(session); Assert.AreEqual("I1+I2*(I3+I4)>0", where, "WHERE clause mismatch."); result = data.Where(d => d.I1 - (d.I2 - d.I3) > 0).ToList(); where = GetLastWhere(session); Assert.AreEqual("I1-(I2-I3)>0", where, "WHERE clause mismatch."); //TODO: write more for math functions, date functions, etc }
public void TestOneToOneRef() { _app = new OneToOneEntityApp(); SetupHelper.DropSchemaObjects("one"); SetupHelper.ActivateApp(_app); var session = _app.OpenSession(); //initial setup session = _app.OpenSession(); var header = session.NewEntity<IDocHeader>(); header.Name = "Doc1"; var det = session.NewEntity<IDocDetails>(); det.Details = "Some details"; det.Header = header; var cm = session.NewEntity<IDocComments>(); cm.Details = det; cm.Comment = "Some comment"; session.SaveChanges(); //test LINQ queries - used to fail var query = session.EntitySet<IDocComments>().Where(dc => dc.Details == det); var cmList = query.ToList(); Assert.IsTrue(cmList.Count == 1, "Expected 1 comment."); //Test can delete method, also used to fail with one-to-one Type[] bt; var canDel = session.CanDeleteEntity(det, out bt); Assert.IsFalse(canDel, "Expected CanDelete = false."); // test [OneToOne] entity // IDocHeader.Details is 'back-ref' property, marked with OneToOne attribute // IDocHeader.Details2 is similar, but we did not create IDocDetails2 record, so it should be null var docId = header.Id; session = _app.OpenSession(); var doc = session.GetEntity<IDocHeader>(docId); var det1 = doc.Details; Assert.IsNotNull(det1, "Expected Details"); var det2 = doc.Details2; Assert.IsNull(det2, "Expected Details2 = null"); //do it again, to check it is correctly cached in record (so it does not blow up) det1 = doc.Details; det2 = doc.Details2; // test using [OneToOne] references in Linq session = _app.OpenSession(); var q2 = session.EntitySet<IDocHeader>().Where(h => h.Details.Details == "Some details"); var docs = q2.ToList(); Assert.AreEqual(1, docs.Count, "Expected Doc header"); }
public void TestModuleIntegration() { var schema = "usr"; SetupHelper.DropSchemaObjects(schema); //start from scratch // Runs integrated app by Randy _app = new EntityApp(); var area = _app.AddArea(schema); var persModule = new Bob.PersonModule(area); var loginModule = new Alice.LoginModule(area, typeof(IPersonExt)); // Now replace original entities with new interfaces; // Alice's IUserStub is already replaced by Randy's IPersonExt. _app.ReplaceEntity(typeof(Alice.ILogin), typeof(IAppLogin)); _app.ReplaceEntity(typeof(Bob.IPerson), typeof(IPersonExt)); // activate SetupHelper.ActivateApp(_app); //Test the resulting solution var session = _app.OpenSession(); var pers = session.NewEntity<IPersonExt>(); pers.FirstName = "John"; pers.LastName = "Dow"; pers.BirthDate = new DateTime(1970, 5, 1); pers.Gender = Gender.Male; var login = session.NewEntity<IAppLogin>(); var loginId = login.Id; login.User = pers; login.UserName = "******"; login.FriendlyName = "JohnD"; login.PasswordHash = 123; login.EmployeeNumber = "E111"; session.SaveChanges(); //Let's try to login the user we created using Alice's method session = _app.OpenSession(); var johnLogin = Alice.LoginModule.Login(session, "johnd", 123); var cmd = session.GetLastCommand(); Assert.IsNotNull(johnLogin, "Login failed"); }
public void TestIdentityInLargeBatch() { _app = new IdentityTestsEntityApp(); SetupHelper.DropSchemaObjects("ident"); SetupHelper.ActivateApp(_app); var saveParamCount = SetupHelper.Driver.MaxParamCount; SetupHelper.Driver.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 SetupHelper.Driver.MaxParamCount = saveParamCount; } }
public void TestEntityReferences() { DeleteAll(); var session = _app.OpenSession(); // Quick test for fix of a bug - entityRef entities are not null (initialized with stubs) on new entities var carx = session.NewEntity <IVehicle>(); var carxOwner = carx.Owner; Assert.IsNull(carxOwner, "EntityRef on new entity is not null!"); session = _app.OpenSession(); var john = session.NewDriver("D001", "John", "Dow"); var johnId = john.Id; var jane = session.NewDriver("D002", "Jane", "Crane"); var janeId = jane.Id; var veh1 = session.NewVehicle("Beatle", 2000, john, john); var car1Id = veh1.Id; var veh2 = session.NewVehicle("Explorer", 2005, john, john); var car2Id = veh2.Id; session.SaveChanges(); //test for a bug fix - New entities were not tracked after save var john2 = session.GetEntity <IDriver>(johnId); Assert.IsTrue(john == john2, "new/saved entity is not tracked."); //Start new session, load all and check that IDs and relationships are correct session = _app.OpenSession(); john = session.GetEntity <IDriver>(johnId); Assert.IsNotNull(john, "John is not found."); Assert.AreEqual(2, john.Vehicles.Count, "Invalid # of cars with John."); veh1 = john.Vehicles[0]; veh2 = john.Vehicles[1]; Assert.IsTrue(veh1.Owner == john, "Car1 owner expected to be John"); Assert.IsTrue(veh2.Owner == john, "Car2 owner expected to be John"); Assert.IsTrue(veh1.Driver == john, "Car1 driver expected to be John"); Assert.IsTrue(veh2.Driver == john, "Car2 driver expected to be John"); //Transfer car2 to jane jane = session.GetEntity <IDriver>(janeId); veh2.Owner = jane; veh2.Driver = null; session.SaveChanges(); //immediately verify that vehicle lists in persons are refreshed Assert.IsTrue(john.Vehicles.Count == 1, "Invlid Vehicle count for John"); Assert.IsTrue(jane.Vehicles.Count == 1, "Invlid Vehicle count for Jane"); session = _app.OpenSession(); john = session.GetEntity <IDriver>(johnId); Assert.AreEqual(1, john.Vehicles.Count, "Invalid # of John's cars after transfer."); jane = session.GetEntity <IDriver>(janeId); Assert.AreEqual(1, jane.Vehicles.Count, "Invalid # of Jane's cars after transfer."); veh2 = jane.Vehicles[0]; Assert.AreEqual(jane, veh2.Owner, "Invalid car2 owner after transfer."); Assert.IsNull(veh2.Driver, "Car2 driver expected to be NULL"); //Check that entity reference is returned initially as record stub session = _app.OpenSession(); veh1 = session.GetEntity <IVehicle>(car1Id); var car1driver = veh1.Driver; var rec = EntityHelper.GetRecord(car1driver); Assert.AreEqual(EntityStatus.Stub, rec.Status, "Entity reference is not loaded as stub."); //Test [PropagateUpdatedOn] attribute. We have this attribute on IVehicle.Owner. Whenever we update a vehicle, // it's owner's UpdatedOn value should change as if the owner entity was updated. session = _app.OpenSession(); jane = session.GetEntity <IDriver>(jane.Id); var janeUpdatedOn = jane.UpdatedOn; Thread.Sleep(200); //let clock tick veh1 = jane.Vehicles[0]; veh1.Year--; //this should cause new value of jane.UpdatedOn session.SaveChanges(); var janeUpdatedOn2 = jane.UpdatedOn; Assert.IsTrue(janeUpdatedOn2 > janeUpdatedOn.AddMilliseconds(50), "PropagateUpdatedOn: expected UpdatedOn of parent entity to change."); //Bug fix: GetEntity with Stub option and invalid pk value - should throw error session = _app.OpenSession(); TestUtil.ExpectFailWith <Exception>(() => { var ent = session.GetEntity <IVehicle>("abc", LoadFlags.Stub); }); // Investigating reported bug var noInstr = session.EntitySet <IDriver>().Where(d => d.Instructor == null).ToList(); Assert.IsTrue(noInstr.Count > 0, "expected some drivers"); }//method
public void TestMisc_EntityReferences() { DeleteAll(); var session = _app.OpenSession(); // Quick test for fix of a bug - entityRef entities are not null (initialized with stubs) on new entities var carx = session.NewEntity <IVehicle>(); var carxOwner = carx.Owner; Assert.IsNull(carxOwner, "EntityRef on new entity is not null!"); session = _app.OpenSession(); var john = session.NewDriver("D001", "John", "Dow"); var johnId = john.Id; var jane = session.NewDriver("D002", "Jane", "Crane"); var janeId = jane.Id; var veh1 = session.NewVehicle("Beatle", 2000, john, john); var car1Id = veh1.Id; var veh2 = session.NewVehicle("Explorer", 2005, john, john); var car2Id = veh2.Id; session.SaveChanges(); //test for a bug fix - New entities were not tracked after save var john2 = session.GetEntity <IDriver>(johnId); Assert.IsTrue(john == john2, "new/saved entity is not tracked."); //Start new session, load all and check that IDs and relationships are correct session = _app.OpenSession(); john = session.GetEntity <IDriver>(johnId); Assert.IsNotNull(john, "John is not found."); Assert.AreEqual(2, john.Vehicles.Count, "Invalid # of cars with John."); veh1 = john.Vehicles[0]; veh2 = john.Vehicles[1]; Assert.IsTrue(veh1.Owner == john, "Car1 owner expected to be John"); Assert.IsTrue(veh2.Owner == john, "Car2 owner expected to be John"); Assert.IsTrue(veh1.Driver == john, "Car1 driver expected to be John"); Assert.IsTrue(veh2.Driver == john, "Car2 driver expected to be John"); //Transfer car2 to jane jane = session.GetEntity <IDriver>(janeId); veh2.Owner = jane; veh2.Driver = null; session.SaveChanges(); //immediately verify that vehicle lists in persons are refreshed Assert.AreEqual(1, john.Vehicles.Count, "Invlid Vehicle count for John"); Assert.AreEqual(1, jane.Vehicles.Count, "Invlid Vehicle count for Jane"); session = _app.OpenSession(); john = session.GetEntity <IDriver>(johnId); Assert.AreEqual(1, john.Vehicles.Count, "Invalid # of John's cars after transfer."); jane = session.GetEntity <IDriver>(janeId); Assert.AreEqual(1, jane.Vehicles.Count, "Invalid # of Jane's cars after transfer."); veh2 = jane.Vehicles[0]; Assert.AreEqual(jane, veh2.Owner, "Invalid car2 owner after transfer."); Assert.IsNull(veh2.Driver, "Car2 driver expected to be NULL"); //Check that entity reference is returned initially as record stub session = _app.OpenSession(); if (Startup.ServerType == DbServerType.MySql) { // MySQL fails without this wait. Looks like we need to give some time to DB engine to settle the update. any ideas?! Thread.Sleep(200); Thread.Sleep(200); Thread.Sleep(200); veh1 = session.GetEntity <IVehicle>(car1Id); // without pause above, it loads NULL into FK driver_id var drId = EntityHelper.GetProperty(veh1, "Driver_Id"); Assert.IsTrue(drId != null, "MySql odd behavior: Driver_Id is null in loaded record."); } else { veh1 = session.GetEntity <IVehicle>(car1Id); } // now the test itself, verify that veh1.Driver is a stub (empty record with just FK values) var car1driver = veh1.Driver; var rec = EntityHelper.GetRecord(car1driver); Assert.AreEqual(EntityStatus.Stub, rec.Status, "Entity reference is not loaded as stub."); //Test [PropagateUpdatedOn] attribute. We have this attribute on IVehicle.Owner. Whenever we update a vehicle, // it's owner's UpdatedOn value should change as if the owner entity was updated. _app.TimeService.SetCurrentOffset(TimeSpan.FromSeconds(5)); //push time forward session = _app.OpenSession(); jane = session.GetEntity <IDriver>(jane.Id); var janeUpdatedOn = jane.UpdatedOn; // Thread.Sleep(200); //let clock tick veh1 = jane.Vehicles[0]; veh1.Year--; //this should cause new value of jane.UpdatedOn session.SaveChanges(); var janeUpdatedOn2 = jane.UpdatedOn; Assert.IsTrue(janeUpdatedOn2 > janeUpdatedOn.AddMilliseconds(50), "PropagateUpdatedOn: expected UpdatedOn of parent entity to change."); _app.TimeService.SetCurrentOffset(TimeSpan.Zero); //Bug fix: GetEntity with Stub option and invalid pk value - should throw error session = _app.OpenSession(); TestUtil.ExpectFailWith <Exception>(() => { var ent = session.GetEntity <IVehicle>("abc", LoadFlags.Stub); }); // Investigating reported bug var noInstr = session.EntitySet <IDriver>().Where(d => d.Instructor == null).ToList(); Assert.IsTrue(noInstr.Count > 0, "expected some drivers"); }//method