public void StaleObjectStateCheckWithNormalizedEntityPersister()
		{
			Top top = new Top();
			top.Name = "original name";

			try
			{
				using (ISession session = OpenSession())
				{
					session.Save(top);
					session.Flush();

					using (ISession concurrentSession = OpenSession())
					{
						Top sameTop = (Top) concurrentSession.Get(typeof(Top), top.Id);
						sameTop.Name = "another name";
						concurrentSession.Flush();
					}

					top.Name = "new name";
					Assert.Throws<StaleObjectStateException>(() => session.Flush());
				}
			}
			finally
			{
				using (ISession session = OpenSession())
				{
					session.Delete("from Top");
					session.Flush();
				}
			}
		}
		public void DynamicUpdate()
		{
			object id;
			Top simple = new Top();

			simple.Name = "saved";

			using (ISession s = OpenSession())
			{
				id = s.Save(simple);
				s.Flush();

				simple.Name = "updated";
				s.Flush();
			}

			using (ISession s = OpenSession())
			{
				simple = (Top) s.Load(typeof(Top), id);
				Assert.AreEqual("updated", simple.Name, "name should have been updated");
			}

			using (ISession s = OpenSession())
			{
				s.Delete("from Top");
				s.Flush();
			}
		}
		public void CollectionPointer()
		{
			ISession s = OpenSession();
			Lower ls = new Lower();
			IList<Top> list = new List<Top>();
			ls.Bag = list;
			Top simple = new Top();
			object id = s.Save(ls);
			s.Save(simple);
			s.Flush();
			list.Add(simple);
			s.Flush();
			s.Close();

			s = OpenSession();
			ls = (Lower) s.Load(typeof(Lower), id);
			Assert.AreEqual(1, ls.Bag.Count);
			s.Delete("from o in class System.Object");
			s.Flush();
			s.Close();
		}
		public void MultiTableManyToOne()
		{
			if (Dialect is MySQLDialect)
			{
				return;
			}

			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			Assert.AreEqual(0, s.CreateQuery("from s in class Top").List().Count);
			Multi multi = new Multi();
			multi.ExtraProp = "extra";
			multi.Name = "name";
			Top simp = new Top();
			simp.Date = DateTime.Now;
			simp.Name = "simp";
			object mid;

			if (Dialect is MsSql2000Dialect)
			{
				mid = s.Save(multi);
			}
			else
			{
				mid = 123L;
				s.Save(multi, mid);
			}
			Lower ls = new Lower();
			ls.Other = ls;
			ls.Another = multi;
			ls.YetAnother = ls;
			ls.Name = "Less Simple";
			object id;
			if (Dialect is MsSql2000Dialect)
			{
				id = s.Save(ls);
			}
			else
			{
				id = 2L;
				s.Save(ls, id);
			}
			t.Commit();
			s.Close();

			Assert.AreSame(ls, ls.Other);
			Assert.AreSame(multi, ls.Another);
			Assert.AreSame(ls, ls.YetAnother);

			s = OpenSession();
			t = s.BeginTransaction();
			ls = (Lower) s.Load(typeof(Lower), id);
			Assert.AreSame(ls, ls.Other);
			Assert.AreSame(ls, ls.YetAnother);
			Assert.AreEqual("name", ls.Another.Name);
			Assert.IsTrue(ls.Another is Multi);
			s.Delete(ls);
			s.Delete(ls.Another);
			t.Commit();
			s.Close();
		}
		public void MultiTableCollections()
		{
			if (Dialect is MySQLDialect)
			{
				return;
			}

			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			Assert.AreEqual(0, s.CreateQuery("from s in class Top").List().Count);
			Multi multi = new Multi();
			multi.ExtraProp = "extra";
			multi.Name = "name";
			Top simp = new Top();
			simp.Date = DateTime.Now;
			simp.Name = "simp";
			object mid;
			object sid;
			if (Dialect is MsSql2000Dialect)
			{
				mid = s.Save(multi);
				sid = s.Save(simp);
			}
			else
			{
				mid = 123L;
				sid = 1234L;
				s.Save(multi, mid);
				s.Save(simp, sid);
			}
			Lower ls = new Lower();
			ls.Other = ls;
			ls.Another = ls;
			ls.YetAnother = ls;
			ls.Name = "Less Simple";
			ls.Set = new HashSet<Top> { multi, simp };

			object id;
			if (Dialect is MsSql2000Dialect)
			{
				id = s.Save(ls);
			}
			else
			{
				id = 2L;
				s.Save(ls, id);
			}
			t.Commit();
			s.Close();
			Assert.AreSame(ls, ls.Other);
			Assert.AreSame(ls, ls.Another);
			Assert.AreSame(ls, ls.YetAnother);

			s = OpenSession();
			t = s.BeginTransaction();
			ls = (Lower) s.Load(typeof(Lower), id);
			Assert.AreSame(ls, ls.Other);
			Assert.AreSame(ls, ls.Another);
			Assert.AreSame(ls, ls.YetAnother);
			Assert.AreEqual(2, ls.Set.Count);

			int foundMulti = 0;
			int foundSimple = 0;

			foreach (object obj in ls.Set)
			{
				if (obj is Top) foundSimple++;
				if (obj is Multi) foundMulti++;
			}
			Assert.AreEqual(2, foundSimple);
			Assert.AreEqual(1, foundMulti);
			Assert.AreEqual(3, s.Delete("from s in class Top"));
			t.Commit();
			s.Close();
		}
		public void MultiTableGeneratedId()
		{
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			Multi multi = new Multi();
			multi.ExtraProp = "extra";
			multi.Name = "name";
			Top simp = new Top();
			simp.Date = DateTime.Now;
			simp.Name = "simp";
			object multiId = s.Save(multi);
			object simpId = s.Save(simp);
			SubMulti sm = new SubMulti();
			sm.Amount = 66.5f;
			object smId = s.Save(sm);
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			multi.ExtraProp += "2";
			multi.Name = "new name";
			s.Update(multi, multiId);
			simp.Name = "new name";
			s.Update(simp, simpId);
			sm.Amount = 456.7f;
			s.Update(sm, smId);
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			multi = (Multi) s.Load(typeof(Multi), multiId);
			Assert.AreEqual("extra2", multi.ExtraProp);
			multi.ExtraProp += "3";
			Assert.AreEqual("new name", multi.Name);
			multi.Name = "newer name";
			sm = (SubMulti) s.Load(typeof(SubMulti), smId);
			Assert.AreEqual(456.7f, sm.Amount);
			sm.Amount = 23423f;
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			multi = (Multi) s.Load(typeof(Top), multiId);
			simp = (Top) s.Load(typeof(Top), simpId);
			Assert.IsFalse(simp is Multi);
			// Can't see the point of this test since the variable is declared as Multi!
			//Assert.IsTrue( multi is Multi );
			Assert.AreEqual("extra23", multi.ExtraProp);
			Assert.AreEqual("newer name", multi.Name);
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			IEnumerable enumer = s.CreateQuery("select\n\ns from s in class Top where s.Count>0").Enumerable();
			bool foundSimp = false;
			bool foundMulti = false;
			bool foundSubMulti = false;

			foreach (object obj in enumer)
			{
				if ((obj is Top) && !(obj is Multi)) foundSimp = true;
				if ((obj is Multi) && !(obj is SubMulti)) foundMulti = true;
				if (obj is SubMulti) foundSubMulti = true;
			}
			Assert.IsTrue(foundSimp);
			Assert.IsTrue(foundMulti);
			Assert.IsTrue(foundSubMulti);

			s.CreateQuery("from m in class Multi where m.Count>0 and m.ExtraProp is not null").List();
			s.CreateQuery("from m in class Top where m.Count>0 and m.Name is not null").List();
			s.CreateQuery("from m in class Lower where m.Other is not null").List();
			s.CreateQuery("from m in class Multi where m.Other.id = 1").List();
			s.CreateQuery("from m in class SubMulti where m.Amount > 0.0").List();

			Assert.AreEqual(2, s.CreateQuery("from m in class Multi").List().Count);
			Assert.AreEqual(3, s.CreateQuery("from s in class Top").List().Count);
			Assert.AreEqual(0, s.CreateQuery("from s in class Lower").List().Count);
			Assert.AreEqual(1, s.CreateQuery("from sm in class SubMulti").List().Count);

			s.CreateQuery("from ls in class Lower, s in elements(ls.Bag) where s.id is not null").List();
			s.CreateQuery("from sm in class SubMulti where exists elements(sm.Children)").List();
			
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			if (TestDialect.SupportsSelectForUpdateOnOuterJoin)
				multi = (Multi) s.Load(typeof(Top), multiId, LockMode.Upgrade);
			simp = (Top) s.Load(typeof(Top), simpId);
			s.Lock(simp, LockMode.UpgradeNoWait);
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			s.Update(multi, multiId);
			s.Delete(multi);
			Assert.AreEqual(2, s.Delete("from s in class Top"));
			t.Commit();
			s.Close();
		}
		public void MultiTable()
		{
			ISession s = OpenSession();
			ITransaction t = s.BeginTransaction();
			Multi multi = new Multi();
			multi.ExtraProp = "extra";
			multi.Name = "name";
			Top simp = new Top();
			simp.Date = DateTime.Now;
			simp.Name = "simp";
			object mid;
			object sid;
			if (Dialect is MsSql2000Dialect)
			{
				mid = s.Save(multi);
				sid = s.Save(simp);
			}
			else
			{
				mid = 123L;
				sid = 1234L;
				s.Save(multi, mid);
				s.Save(simp, sid);
			}
			SubMulti sm = new SubMulti();
			sm.Amount = 66.5f;
			object smid;
			if (Dialect is MsSql2000Dialect)
			{
				smid = s.Save(sm);
			}
			else
			{
				smid = 2L;
				s.Save(sm, smid);
			}
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			multi.ExtraProp = multi.ExtraProp + "2";
			multi.Name = "new name";
			s.Update(multi, mid);
			simp.Name = "new name";
			s.Update(simp, sid);
			sm.Amount = 456.7f;
			s.Update(sm, smid);
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			multi = (Multi) s.Load(typeof(Multi), mid);
			Assert.AreEqual("extra2", multi.ExtraProp);
			multi.ExtraProp = multi.ExtraProp + "3";
			Assert.AreEqual("new name", multi.Name);
			multi.Name = "newer name";
			sm = (SubMulti) s.Load(typeof(SubMulti), smid);
			Assert.AreEqual(456.7f, sm.Amount);
			sm.Amount = 23423f;
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			multi = (Multi) s.Load(typeof(Top), mid);
			simp = (Top) s.Load(typeof(Top), sid);
			Assert.IsFalse(simp is Multi);
			Assert.AreEqual("extra23", multi.ExtraProp);
			Assert.AreEqual("newer name", multi.Name);
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			IEnumerator enumer = s.CreateQuery("select\n\ns from s in class Top where s.Count>0").Enumerable().GetEnumerator();
			bool foundSimp = false;
			bool foundMulti = false;
			bool foundSubMulti = false;
			while (enumer.MoveNext())
			{
				object o = enumer.Current;
				if ((o is Top) && !(o is Multi)) foundSimp = true;
				if ((o is Multi) && !(o is SubMulti)) foundMulti = true;
				if (o is SubMulti) foundSubMulti = true;
			}
			Assert.IsTrue(foundSimp);
			Assert.IsTrue(foundMulti);
			Assert.IsTrue(foundSubMulti);

			s.CreateQuery("from m in class Multi where m.Count>0 and m.ExtraProp is not null").List();
			s.CreateQuery("from m in class Top where m.Count>0 and m.Name is not null").List();
			s.CreateQuery("from m in class Lower where m.Other is not null").List();
			s.CreateQuery("from m in class Multi where m.Other.id = 1").List();
			s.CreateQuery("from m in class SubMulti where m.Amount > 0.0").List();

			Assert.AreEqual(2, s.CreateQuery("from m in class Multi").List().Count);

			//if( !(dialect is Dialect.HSQLDialect) ) 
			//{
			Assert.AreEqual(1, s.CreateQuery("from m in class Multi where m.class = SubMulti").List().Count);
			Assert.AreEqual(1, s.CreateQuery("from m in class Top where m.class = Multi").List().Count);
			//}

			Assert.AreEqual(3, s.CreateQuery("from s in class Top").List().Count);
			Assert.AreEqual(0, s.CreateQuery("from ls in class Lower").List().Count);
			Assert.AreEqual(1, s.CreateQuery("from sm in class SubMulti").List().Count);

			s.CreateQuery("from ls in class Lower, s in elements(ls.Bag) where s.id is not null").List();
			s.CreateQuery("from ls in class Lower, s in elements(ls.Set) where s.id is not null").List();
			s.CreateQuery("from sm in class SubMulti where exists elements(sm.Children)").List();

			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			if (TestDialect.SupportsSelectForUpdateOnOuterJoin)
				multi = (Multi)s.Load(typeof(Top), mid, LockMode.Upgrade);
			simp = (Top) s.Load(typeof(Top), sid);
			s.Lock(simp, LockMode.UpgradeNoWait);
			t.Commit();
			s.Close();

			s = OpenSession();
			t = s.BeginTransaction();
			s.Update(multi, mid);
			s.Delete(multi);
			Assert.AreEqual(2, s.Delete("from s in class Top"));
			t.Commit();
			s.Close();
		}