让我告诉你,其中一种选择。对于这个草案,我希望确实有LookupColumn1Id
NULL 的记录将扮演 的角色Department
,其余的将扮演Employee
.
实体可能如下所示:
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),而不是在映射中。
原因是缺少将扮演鉴别器角色的列。这就是为什么我们使用带有WHERE
属性的映射(参见 xml 中的类元素),通过查找列的存在来区分Department
和Employee