Map Entities to self-joined Table by Id

≯℡__Kan透↙ 提交于 2020-01-05 05:48:04

问题


My legacy table "AllData" has those columns:Id, Title, LookupColumn1Id My entities:

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; }
}

I want to generate SELECT like this:

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)       

回答1:


Let me show you, one of the options. For this draft, I'd expect, that records which do have LookupColumn1Id NULL will play the role of the Department, the rest will play the role of Employee.

The Entities could look like this:

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 
}

The mapping could be like this:

<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>

This mapping, for read access (the required SELECT) is working. Now, we can create a query:

[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());
}

This scenario in general will work, but what we did, is the inheritance only in C# (both derived from BaseEntity), while not in the mapping.

The reason is, the missing column which would play the Discriminator role. That's why we are using the mapping with a WHERE attribute (see class element in xml), distinguishing the Department and Employee by the lookup column presence



来源:https://stackoverflow.com/questions/19136749/map-entities-to-self-joined-table-by-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!