流畅的hibernate一对多集合,由enum过滤

本文关键字:enum 过滤 集合 一对多 hibernate | 更新日期: 2023-09-27 18:14:37

我觉得我的设计有问题。

我有一个类叫做office
class Office
{
    public virtual long Id { get; set; }
    public virtual string Code { get; set; }
    public virtual IList<Person> Managers { get; set; }
    public virtual IList<Person> Developers { get; set; }
    public virtual IList<Person> TeaMakers { get; set; }
}

和Person类

class Person
{
    public virtual long Id { get; set; }
    public virtual string Name {get; set;}
    public virtual StaffType Type { get; set;}
    public virtual Office Office { get; set; }
}

和一个名为StaffType

的enum
public enum StaffType
{
   MANAGER,
   DEVELOPER,
   TEAMAKER
}

映射Person表很容易:

public class PersonMap: ClassMap<Person>    
{
   public PersonMap()
   {
     Table("Person");
     Id(x => x.Id);
     Map(x => x.Name);
     References(x => x.Office).ForeignKey("Id").Not.Nullable()
     Map(x => x.Type).CustomType<StaffType>();
   }
}

但是我被办公室的地图难住了。我如何让地图使用枚举来过滤3个列表?

如果我这样做:

public class OfficeMap: ClassMap<Office>    
{
    public static string TableName = "Office";
    public static string MappingColumn = TableName + "Id";

   public OfficeMap()
   {
      Table(TableName);
      Id(x => x.Id);
      Map(x = x.Code);
      HasMany(x => x.Managers)
            .Cascade.AllDeleteOrphan()
            .Fetch.Select()
            .Inverse().KeyColumn(MappingColumn);
     HasMany(x => x.Developers)
            .Cascade.AllDeleteOrphan()
            .Fetch.Select()
            .Inverse().KeyColumn(MappingColumn);
    HasMany(x => x.TeaMakers)
            .Cascade.AllDeleteOrphan()
            .Fetch.Select()
            .Inverse().KeyColumn(MappingColumn);
   }
}

流畅性不知道如何通过StaffType enum将3个集合分开

Thanks for the help

额外注意:Person表的Type字段总是被映射为int类型。

流畅的hibernate一对多集合,由enum过滤

NHibernate支持将过滤作为映射的一部分。请在这里阅读更多6.2。映射一个集合。

技巧是在映射中添加更多的SQL。实际上,是一些WHERE条件,将在收集加载期间求值。文档中的一小段摘录:
<map // or <set or <bag ...
    name="propertyName"                                         (1)
    table="table_name"                                          (2)
    ...
    where="arbitrary sql where condition"                       (9)

和WHERE:

的描述

where(可选)指定要使用的任意SQL where条件检索或删除集合时(如果集合应该只包含可用数据的一个子集)

在您的例子中,流畅的语法是类似的:...Where("MyColumn = 'myValue' ");

解决方案草稿:

...
HasMany(x => x.Managers)
   .Cascade.AllDeleteOrphan()
   .Fetch.Select()
   .Inverse().KeyColumn(MappingColumn)
   .Where("Type = 1") // the Column name in the Person table
;                     // and the value 1 as the enum of the Manager
...
// The same for the others

我将其建模为简单的一对多(Office有许多人),并向IEnumerable<Person>添加扩展方法以按StaffType过滤。如果需要,您可以通过AddManager等方法封装对Person集合的访问,这些方法强制执行业务规则。