流畅的nhibernate一对多集合,由枚举过滤

时间:2013-05-20 07:56:09

标签: c# nhibernate fluent-nhibernate one-to-many

我想我在这里有设计问题。

基本上我有一个名为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的枚举

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枚举来分割3个集合

感谢您的帮助

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

2 个答案:

答案 0 :(得分:0)

NHibernate支持过滤作为映射的一部分。请在这里阅读更多6.2. Mapping a Collection

诀窍是在映射中添加更多SQL。实际上,一些WHERE Con​​dition,在集合加载期间要进行评估。文档中的小摘录:

<map // or <set or <bag ...
    name="propertyName"                                         (1)
    table="table_name"                                          (2)
    ...
    where="arbitrary sql where condition"                       (9)

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

答案 1 :(得分:0)

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