Nhibernate 按Id将实体映射到自联接表
我的旧表AllData有以下列:Id、标题、LookupColumn1Id 我的实体:Nhibernate 按Id将实体映射到自联接表,nhibernate,nhibernate-mapping,nhibernate-criteria,Nhibernate,Nhibernate Mapping,Nhibernate Criteria,我的旧表AllData有以下列:Id、标题、LookupColumn1Id 我的实体: public class BaseEntity { public virtual int Id { get; set; } public virtual string Name { get; set; } } public class Employee: BaseEntity { public virtual int DepartmentId { get; set; } p
public class BaseEntity
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class Employee: BaseEntity
{
public virtual int DepartmentId { get; set; }
public virtual string DepartmentName { get; set; }
}
public class Department: BaseEntity
{
public virtual int HeadManagerId { get; set; }
}
我想生成如下选择:
SELECT EmployeeTable.Title, DepartmentTable.Id, DepartmentTable.Title
FROM AllData EmployeeTable left outer join AllData DepartmentTable on EmployeeTable.LookupColumn1Id=DepartmentTable.Id
WHERE EmployeeTable.tp_ListId = @p0 and (DepartmentTable.Title = @p1)
public class BaseEntity
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class Employee : BaseEntity
{
public virtual Department Department { get; set; } // to lookup record
}
public class Department : BaseEntity
{
public virtual IList<Employee> Employees { get; set; } // the way back
}
<class name="Department" table="[dbo].[AllData]" lazy="true" batch-size="25"
where="LookupColumn1Id IS NULL" >
<id name="Id" column="Id" generator="native" />
<property not-null="true" name="Name" column="Title" />
<bag name="Employees" >
<key column="LookupColumn1Id" />
<one-to-many class="Employee"/>
</bag>
</class>
<class name="Employee1" table="[dbo].[AllData]" lazy="true" batch-size="25"
where="LookupColumn1Id IS NOT NULL" >
<id name="Id" column="Id" generator="native" />
<property not-null="true" name="Name" column="Title" />
<many-to-one name="Department" class="Department" column="LookupColumn1Id " />
</class>
让我给你看看,其中一个选择。对于这个草案,我希望那些确实具有LookupColumn1Id为NULL的记录将扮演部门的角色,其余的将扮演员工的角色 实体可以如下所示:
SELECT EmployeeTable.Title, DepartmentTable.Id, DepartmentTable.Title
FROM AllData EmployeeTable left outer join AllData DepartmentTable on EmployeeTable.LookupColumn1Id=DepartmentTable.Id
WHERE EmployeeTable.tp_ListId = @p0 and (DepartmentTable.Title = @p1)
public class BaseEntity
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class Employee : BaseEntity
{
public virtual Department Department { get; set; } // to lookup record
}
public class Department : BaseEntity
{
public virtual IList<Employee> Employees { get; set; } // the way back
}
<class name="Department" table="[dbo].[AllData]" lazy="true" batch-size="25"
where="LookupColumn1Id IS NULL" >
<id name="Id" column="Id" generator="native" />
<property not-null="true" name="Name" column="Title" />
<bag name="Employees" >
<key column="LookupColumn1Id" />
<one-to-many class="Employee"/>
</bag>
</class>
<class name="Employee1" table="[dbo].[AllData]" lazy="true" batch-size="25"
where="LookupColumn1Id IS NOT NULL" >
<id name="Id" column="Id" generator="native" />
<property not-null="true" name="Name" column="Title" />
<many-to-one name="Department" class="Department" column="LookupColumn1Id " />
</class>
映射可以如下所示:
SELECT EmployeeTable.Title, DepartmentTable.Id, DepartmentTable.Title
FROM AllData EmployeeTable left outer join AllData DepartmentTable on EmployeeTable.LookupColumn1Id=DepartmentTable.Id
WHERE EmployeeTable.tp_ListId = @p0 and (DepartmentTable.Title = @p1)
public class BaseEntity
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class Employee : BaseEntity
{
public virtual Department Department { get; set; } // to lookup record
}
public class Department : BaseEntity
{
public virtual IList<Employee> Employees { get; set; } // the way back
}
<class name="Department" table="[dbo].[AllData]" lazy="true" batch-size="25"
where="LookupColumn1Id IS NULL" >
<id name="Id" column="Id" generator="native" />
<property not-null="true" name="Name" column="Title" />
<bag name="Employees" >
<key column="LookupColumn1Id" />
<one-to-many class="Employee"/>
</bag>
</class>
<class name="Employee1" table="[dbo].[AllData]" lazy="true" batch-size="25"
where="LookupColumn1Id IS NOT NULL" >
<id name="Id" column="Id" generator="native" />
<property not-null="true" name="Name" column="Title" />
<many-to-one name="Department" class="Department" column="LookupColumn1Id " />
</class>
此映射,对于读取访问,所需的SELECT正在工作。现在,我们可以创建一个查询:
[TestMethod]
public void TestAllData()
{
var session = NHSession.GetCurrent();
// the Employee Criteria
var criteria = session.CreateCriteria<Employee>();
// joined with the Department
var deptCrit = criteria.CreateCriteria("Department", JoinType.LeftOuterJoin);
// here we can filter Department
deptCrit.Add(Restrictions.Eq("Name", "Dep Name"));
// here we can filter Employee
criteria.Add(Restrictions.Eq("Name", "Emp Name"));
// the SELECT
var results = criteria
.List<Employee>();
Assert.IsTrue(results.IsNotEmpty());
var employee = results.First();
// check if all data are injected into our properties
Assert.IsTrue(employee.Name.IsNotEmpty());
Assert.IsTrue(employee.Department.Name.IsNotEmpty());
}
这个场景通常可以工作,但我们所做的是,只在C中进行继承,这两者都是从BaseEntity派生的,而不是在映射中
原因是,缺少将起到鉴别器作用的列。这就是为什么我们在xml中使用带有WHERE属性see class元素的映射,通过查找列presence区分部门和员工谢谢,但这不是答案。我不会在代码中显式地实现该层上实体之间的关系,我只想在映射中指定特定的关系。换句话说,您正在将表访问移到实体/对象访问。这意味着,我们必须将表映射到实体,根据它们的数据库和对象结构创建关系。然后我们可以通过对象模型的抽象来查询数据库