private static void CreateSampleData(ISession session) { using (var transaction = session.BeginTransaction()) { // create a couple of Stores each with some Products and Employees var barginBasin = new Store { Name = "Bargin Basin" }; var superMart = new Store { Name = "SuperMart" }; var potatoes = new Product { Name = "Potatoes", Price = 3.60 }; var fish = new Product { Name = "Fish", Price = 4.49 }; var milk = new Product { Name = "Milk", Price = 0.79 }; var bread = new Product { Name = "Bread", Price = 1.29 }; var cheese = new Product { Name = "Cheese", Price = 2.10 }; var waffles = new Product { Name = "Waffles", Price = 2.41 }; var daisy = new Employee { FirstName = "Daisy", LastName = "Harrison" }; var jack = new Employee { FirstName = "Jack", LastName = "Torrance" }; var sue = new Employee { FirstName = "Sue", LastName = "Walkters" }; var bill = new Employee { FirstName = "Bill", LastName = "Taft" }; var joan = new Employee { FirstName = "Joan", LastName = "Pope" }; // add products to the stores, there's some crossover in the products in each // store, because the store-product relationship is many-to-many AddProductsToStore(barginBasin, potatoes, fish, milk, bread, cheese); AddProductsToStore(superMart, bread, cheese, waffles); // add employees to the stores, this relationship is a one-to-many, so one // employee can only work at one store at a time AddEmployeesToStore(barginBasin, daisy, jack, sue); AddEmployeesToStore(superMart, bill, joan); // save both stores, this saves everything else via cascading session.SaveOrUpdate(barginBasin); session.SaveOrUpdate(superMart); transaction.Commit(); } }
public virtual void AddEmployee(Employee employee) { employee.Store = this; Staff.Add(employee); }
static void Main(string[] args) { bool bCreateOrUpdateSchema = true; bool bCreateSampleData = false || bCreateOrUpdateSchema; var sessionFactory = CreateSessionFactory(bCreateOrUpdateSchema); using (var session = sessionFactory.OpenSession()) { if (bCreateSampleData) { CreateSampleData(session); } // get an entity by ID: int employeeID = 1; var emp = session.Get<Employee>(employeeID); Console.WriteLine(String.Format("Employee ID {0} = {1}", employeeID, emp.FirstName)); int storeID = 1; var store = session.Get<Store>(storeID); Console.WriteLine(String.Format("Store ID {0} = {1}", storeID, store.Name)); // add a new employee: var newEmp = new Employee { FirstName = "Buzz", LastName = "Lightyear" }; store.AddEmployee(newEmp); session.Flush(); // query an entity using criteria query: var crit = session.CreateCriteria<Employee>() .Add(Expression.Eq("FirstName", "Buzz")); IList<Employee> emps = crit.List<Employee>(); foreach (var empl in emps) { Console.WriteLine("Employee :" + empl.FirstName); } // modify an employee: emp = emps.First(); emp.LastName = "Smith"; session.Flush(); // list all employees in a store foreach (var empl in store.Staff) { Console.WriteLine(String.Format("Store {0} employee: {1} {2}", store.Name, empl.FirstName, empl.LastName)); } // delete all Buzzes emps = session.CreateCriteria<Employee>() .Add(Expression.Eq("FirstName", "Buzz")) .List<Employee>(); foreach (var empl in emps) { Console.WriteLine(String.Format("Deleting employee {0} {1}", empl.FirstName, empl.LastName)); // you must remove the entity from associated collections, if you only do session.delete, you get an exception when doing session.flush() store.Staff.Remove(empl); session.Delete(empl); } session.Flush(); // re-list employees for one store: foreach (var empl in store.Staff) { Console.WriteLine(String.Format("Store {0} employee: {1} {2}", store.Name, empl.FirstName, empl.LastName)); } // two in memory instances of the same entity, NHibernate is smart enough to get emp2 from the in memory version(not going back to the database) // or at least the changes to emp1 are reflected in emp2: var emp1 = session.Get<Employee>(1); emp1.FirstName = "Sally"; var emp2 = session.Get<Employee>(1); Console.WriteLine(String.Format("First employee instance: {0} {1}, second employee instance {2} {3}", emp1.FirstName, emp2.LastName, emp2.FirstName, emp2.LastName)); // its also smart enough to update other instances of the employee when we do this: emp1.FirstName = "Daisy"; emp2.FirstName = "Sarah"; Console.WriteLine(); // both emp1 and emp2 now have a firstname of "Sarah" Console.WriteLine(String.Format("First employee instance: {0} {1}, second employee instance {2} {3}", emp1.FirstName, emp2.LastName, emp2.FirstName, emp2.LastName)); session.Flush(); // are queries smart enough to use already loaded objects? var empQuery = session.CreateCriteria<Employee>() .Add(Expression.Eq("FirstName", "Sarah")) .Add(Expression.Eq("LastName", "Harrison")); emp1 = empQuery.List<Employee>().First(); emp1.FirstName = "Danielle"; var empQuery2 = session.CreateCriteria<Employee>() .Add(Expression.Eq("FirstName", "Danielle")); // this query returns nothing, because it goes back to the database: Console.WriteLine("Query results for firstname=Danielle:"); foreach (var empl in empQuery2.List<Employee>()) { Console.WriteLine(String.Format("{0} {1}", empl.FirstName, empl.LastName)); } // we could probably re-use empQuery here, (but has that already been evaluated? if we call .List() again does it re-query?) var empQuery3 = session.CreateCriteria<Employee>() .Add(Expression.Eq("FirstName", "Sarah")); // this query returns a value because the firstname is still sarah in the database // but the value displayed is from the in-memory version, so the results of the query shows "danielle", not "sarah": Console.WriteLine("Query results for firstname=Sarah:"); foreach (var empl in empQuery3.List<Employee>()) { Console.WriteLine(String.Format("{0} {1}", empl.FirstName, empl.LastName)); } Console.WriteLine("Press any key to exit"); Console.ReadKey(); } }