public void Entities_with_relation_mapped_as_both_reference_and_foreign_key_value_can_be_written_and_read_back_again_using_join()
        {
            var company1 = new Company
                {
                    Name = "Company 1"
                };
            var company2 = new Company
                {
                    Name = "Company 2"
                };

            var employee1 = new Employee
                {
                    FirstName = "Steve",
                    LastName = "Smith",
                    BirthDate = new DateTime(1972, 1, 2),
                };

            var employee2 = new Employee
                {
                    FirstName = "John",
                    LastName = "Johnsson",
                    BirthDate = new DateTime(1954, 11, 12),
                };

            company1.AddEmployee(employee1);
            company1.AddEmployee(employee2);

            Repository.Insert(company1, company2);
            Repository.Insert(employee1, employee2);

            employee2.BirthDate = new DateTime(1965, 1, 1);

            Repository.Update(employee2);
            Repository.Update<Employee>()
                      .Set(x => x.CompanyId, company2.Id)
                      .Where(x => x.Id == employee2.Id)
                      .Execute();

            var allCompanies = Repository.Find<Company>()
                                         .OrderBy(x => x.Name)
                                         .Join<Company, Employee>(x => x.Employees, x => x.Company)
                                         .ExecuteList();

            var actualEmployee2 = Repository.Find<Employee>()
                                            .Where(x => x.Id == employee2.Id)
                                            .Join<Company, Employee>(x => x.Employees, x => x.Company)
                                            .Execute();

            // Set up original entities to match the expected result
            company1.RemoveEmployee(employee2);
            company2.AddEmployee(employee2);

            employee1.RefreshReferencedIds();
            employee2.RefreshReferencedIds();

            Assert.AreEqual(company1, allCompanies[0]);
            Assert.AreEqual(company2, allCompanies[1]);
            Assert.AreEqual(employee2, actualEmployee2);
        }
        public void Update_can_be_performed_by_setting_a_reference_property_to_another_entity()
        {
            var company1 = new Company
                {
                    Name = "Company 1"
                };
            var company2 = new Company
                {
                    Name = "Company 2"
                };

            var employee1 = new Employee
                {
                    FirstName = "Steve",
                    LastName = "Smith",
                    BirthDate = new DateTime(1972, 1, 2),
                };

            var employee2 = new Employee
                {
                    FirstName = "John",
                    LastName = "Johnsson",
                    BirthDate = new DateTime(1954, 11, 12),
                };

            company1.AddEmployee(employee1);
            company1.AddEmployee(employee2);

            Repository.Insert(company1, company2);
            Repository.Insert(employee1, employee2);

            Repository.Update<Employee>()
                      .Set(x => x.Company, company2)
                      .Where(x => x.Id == employee2.Id)
                      .Execute();

            var allCompanies = Repository.Find<Company>()
                                         .OrderBy(x => x.Name)
                                         .Join<Company, Employee>(x => x.Employees, x => x.Company)
                                         .ExecuteList();

            // Set up original entities to match the expected result
            company1.RemoveEmployee(employee2);
            company2.AddEmployee(employee2);

            employee1.RefreshReferencedIds();
            employee2.RefreshReferencedIds();

            Assert.AreEqual(company1, allCompanies[0]);
            Assert.AreEqual(company2, allCompanies[1]);
        }
        public void Condition_can_be_placed_on_table_without_alias_when_joining_with_aliased_table()
        {
            var company = new Company
                {
                    Name = "Company 1"
                };

            var employee1 = new Employee
                {
                    LastName = "Employee 1"
                };

            var employee2 = new Employee
                {
                    LastName = "Employee 2"
                };

            var employee3 = new Employee
                {
                    LastName = "Employee 3"
                };

            var manager1 = new Employee
                {
                    LastName = "Manager"
                };

            var manager2 = new Employee
                {
                    LastName = "Manager 2"
                };

            Repository.Insert(company);

            company.AddEmployee(employee1);
            company.AddEmployee(employee2);
            company.AddEmployee(employee3);
            company.AddEmployee(manager1);
            company.AddEmployee(manager2);

            Repository.Insert(manager1, manager2);

            // Add the subordinates after the managers have been saved so that the
            // ManagerIds are set to the correct values
            manager1.AddSubordinate(employee1);
            manager1.AddSubordinate(employee2);
            manager2.AddSubordinate(employee3);

            Repository.Insert(employee1, employee2, employee3);

            var actualEmployees = Repository.Find<Employee>()
                                            .Where(x => x.ManagerId == manager1.Id)
                                            .Join<Employee, Employee>(x => x.Subordinates, x => x.Manager, parentAlias: "Manager", childAlias: null)
                                            .OrderBy(x => x.LastName)
                                            .ExecuteList();

            Assert.AreEqual(2, actualEmployees.Count);

            AssertEqualsManagerAndSubordinates(employee1, actualEmployees[0]);
            AssertEqualsManagerAndSubordinates(employee2, actualEmployees[1]);
        }
        public void Query_with_filter_on_explicit_null_value_generates_an_IS_NULL_condition_in_the_query()
        {
            var company1 = new Company { Name = "Company1" };
            var company2 = new Company { Name = null };
            var company3 = new Company { Name = "Company2" };
            var company4 = new Company { Name = null };

            Repository.Insert(company1, company2, company3, company4);

            var actualCompanies = Repository.Find<Company>().Where(x => x.Name == (string)null).ExecuteList();

            CollectionAssert.AreEquivalent(new[] { company2, company4 }, actualCompanies);
        }
        public void Relationship_for_entity_with_both_foreign_key_id_property_and_navigation_property_can_be_changed_by_setting_the_foreign_key_id_even_though_the_navigation_property_is_null()
        {
            var company1 = new Company
                {
                    Name = "Company 1"
                };
            var company2 = new Company
                {
                    Name = "Company 2"
                };

            var employee1 = new Employee
                {
                    FirstName = "Steve",
                    LastName = "Smith",
                    BirthDate = new DateTime(1972, 1, 2),
                };

            Repository.Insert(company1, company2);

            employee1.Company = company1;

            Repository.Insert(employee1);

            var readEmployeeBeforeUpdate = Repository.Find<Employee>().Where(x => x.Id == employee1.Id).Execute();

            Assert.AreEqual(company1.Id, readEmployeeBeforeUpdate.CompanyId);

            readEmployeeBeforeUpdate.CompanyId = company2.Id;

            Repository.Update(readEmployeeBeforeUpdate);

            var readEmployeeAfterUpdate = Repository.Find<Employee>().Where(x => x.Id == employee1.Id).Execute();

            Assert.AreEqual(company2.Id, readEmployeeAfterUpdate.CompanyId);
        }
        public virtual void Object_can_join_two_child_collections_using_only_parent_to_child_relation()
        {
            var company1 = new Company { Name = "Company 1" };
            var company2 = new Company { Name = "Company 2" };

            var employee1 = new Employee
                {
                    FirstName = "Steve",
                    LastName = "Smith",
                    BirthDate = new DateTime(1972, 1, 2),
                };

            var employee2 = new Employee
                {
                    FirstName = "Lisa",
                    LastName = "Johnsson",
                    BirthDate = new DateTime(1954, 11, 12),
                };

            var employee3 = new Employee
                {
                    FirstName = "Nisse",
                    LastName = "Karlsson",
                    BirthDate = new DateTime(1972, 1, 3),
                };

            var department1 = new Department("department 1");
            var department2 = new Department("department 2");
            var department3 = new Department("department 3");

            Repository.Insert(company1, company2);

            company1.AddEmployee(employee1);
            company1.AddEmployee(employee2);
            company1.AddEmployee(employee3);
            company1.AddDepartment(department1);
            company1.AddDepartment(department2);
            company1.AddDepartment(department3);

            Repository.Insert(employee1, employee2, employee3);
            Repository.Insert(department1, department2, department3);

            var actualCompany1 = Repository.Find<Company>()
                                            .Where(x => x.Id == company1.Id)
                                            .Join(x => x.Employees, x => x.CompanyId)
                                            .Join(x => x.Departments, x => x.CompanyId)
                                            .ExecuteList();

            Assert.AreEqual(actualCompany1, actualCompany1);
        }
        public void Navigation_property_id_value_takes_precedence_over_explicit_foreign_key_id_property_value_when_both_are_set()
        {
            var company1 = new Company
                {
                    Name = "Company 1"
                };
            var company2 = new Company
                {
                    Name = "Company 2"
                };

            var employee1 = new Employee
                {
                    FirstName = "Steve",
                    LastName = "Smith",
                    BirthDate = new DateTime(1972, 1, 2),
                };

            Repository.Insert(company1, company2);

            employee1.Company = company1;
            employee1.CompanyId = company2.Id;

            Repository.Insert(employee1);

            var actualEmployee = Repository.Find<Employee>().Where(x => x.Id == employee1.Id).Execute();

            Assert.AreEqual(company1.Id, actualEmployee.CompanyId);
        }
        public virtual void Collections_are_loaded_correctly_for_query_fetching_only_a_single_entity_where_entity_is_joined_to_itself_with_multiple_collections_using_only_parent_to_child_relation()
        {
            var company1 = new Company
            {
                Name = "Company 1"
            };

            Repository.Insert(company1);

            var employee1 = new Employee("firstname1", "lastname1");
            var employee2 = new Employee("firstname2", "lastname2");
            var employee3 = new Employee("firstname3", "lastname3");
            var employee4 = new Employee("firstname4", "lastname4");
            var employee5 = new Employee("firstname5", "lastname5");
            var employee6 = new Employee("firstname6", "lastname6");

            company1.AddEmployee(employee1);
            company1.AddEmployee(employee2);
            company1.AddEmployee(employee3);
            company1.AddEmployee(employee4);
            company1.AddEmployee(employee5);
            company1.AddEmployee(employee6);

            Repository.Insert(employee1); // Insert employee1 first since all the others reference that one

            employee1.AddMentee(employee2);
            employee1.AddMentee(employee3);

            employee1.AddSubordinate(employee4);
            employee1.AddSubordinate(employee5);

            Repository.Insert(employee2, employee3, employee4, employee5, employee6);

            var actualEmployee1 = Repository.Find<Employee>(primaryAlias: "manager")
                                            .Where<Employee>("manager", x => x.Id == employee1.Id)
                                            .OrWhere<Employee>("mentor", x => x.Id == employee1.Id)
                                            .Join(x => x.Subordinates, x => x.ManagerId, "manager", null)
                                            .Join(x => x.Mentees, x => x.MentorId, "mentor", null)
                                            .OrderBy(x => x.LastName)
                                            .OrderBy<Employee>("manager", x => x.LastName)
                                            .OrderBy<Employee>("mentor", x => x.LastName)
                                            .Execute();

            Assert.AreEqual(2, actualEmployee1.Mentees.Count);
            Assert.AreEqual("lastname2", actualEmployee1.Mentees[0].LastName);
            Assert.AreEqual("lastname3", actualEmployee1.Mentees[1].LastName);

            Assert.AreEqual(2, actualEmployee1.Subordinates.Count);
            Assert.AreEqual("lastname4", actualEmployee1.Subordinates[0].LastName);
            Assert.AreEqual("lastname5", actualEmployee1.Subordinates[1].LastName);
        }
        public void Entity_can_be_joined_to_itself_without_constraints()
        {
            var company = new Company
                {
                    Name = "Company 1"
                };

            var employee1 = new Employee
                {
                    LastName = "Employee 1"
                };

            var employee2 = new Employee
                {
                    LastName = "Employee 2"
                };

            var employee3 = new Employee
                {
                    LastName = "Employee 3"
                };

            var manager1 = new Employee
                {
                    LastName = "Manager"
                };

            var manager2 = new Employee
                {
                    LastName = "Manager 2"
                };

            Repository.Insert(company);

            company.AddEmployee(employee1);
            company.AddEmployee(employee2);
            company.AddEmployee(employee3);
            company.AddEmployee(manager1);
            company.AddEmployee(manager2);

            Repository.Insert(manager1, manager2);

            // Add the subordinates after the managers have been saved so that the
            // ManagerIds are set to the correct values
            manager1.AddSubordinate(employee1);
            manager1.AddSubordinate(employee2);
            manager2.AddSubordinate(employee3);

            Repository.Insert(employee1, employee2, employee3);

            var actualEmployees = Repository.Find<Employee>()
                                            .Join<Employee, Employee>(x => x.Subordinates, x => x.Manager, parentAlias: "Manager", childAlias: null)
                                            .OrderBy(x => x.LastName)
                                            .ExecuteList();

            Assert.AreEqual(5, actualEmployees.Count);

            AssertEqualsManagerAndSubordinates(employee1, actualEmployees[0]);
            AssertEqualsManagerAndSubordinates(employee2, actualEmployees[1]);
            AssertEqualsManagerAndSubordinates(employee3, actualEmployees[2]);
            AssertEqualsManagerAndSubordinates(manager1, actualEmployees[3]);
            AssertEqualsManagerAndSubordinates(manager2, actualEmployees[4]);
        }
        public void Entities_with_relation_mapped_as_both_reference_and_foreign_key_value_can_be_written_and_read_back_again_using_single_table_query()
        {
            var company1 = new Company
                {
                    Name = "Company 1"
                };

            var employee1 = new Employee
                {
                    FirstName = "Steve",
                    LastName = "Smith",
                    BirthDate = new DateTime(1972, 1, 2),
                    Company = company1
                };

            var employee2 = new Employee
                {
                    FirstName = "John",
                    LastName = "Johnsson",
                    BirthDate = new DateTime(1954, 11, 12),
                    Company = company1
                };

            Repository.Insert(company1);
            Repository.Insert(employee1, employee2);

            var actualEmployees = Repository.Find<Employee>()
                                            .OrderBy(x => x.BirthDate)
                                            .ExecuteList();

            Assert.AreEqual(2, actualEmployees.Count);

            Assert.IsNull(actualEmployees[0].Company);
            Assert.IsNull(actualEmployees[1].Company);
            Assert.AreEqual(company1.Id, actualEmployees[0].CompanyId);
            Assert.AreEqual(company1.Id, actualEmployees[1].CompanyId);
        }