Fluent NHibernate:将属性应用于通过Component映射的属性的所有成员

时间:2011-08-10 16:55:17

标签: nhibernate fluent-nhibernate nhibernate-mapping

我正在使用Fluent NHibernate(1.2),我正致力于实现列级加密。我有一个处理加密的自定义类型,因此域模型可以具有本机明文数据类型(简单字符串,整数,日期时间等),并且所有加密/解密工作都在幕后。

我想指定每个域模型中的哪些属性通过属性加密,并使用约定来指定这些属性的自定义类型,以便域模型是很好的POCO,而不提及自定义类型:< / p>

public class EncryptedAttribute : Attribute {}

public class UserRecord {
  public virtual Guid Id { get; set; }
  public virtual string Username { get; set; }
  [Encrypted]
  public virtual string EmailAddress { get; set; }
  [Encrypted]
  public virtual DateTime DateOfBirth { get; set; }
  [Encrypted]
  public virtual PersonName LegalName { get; set; }
  // etc.
}

public class PersonName {
  public virtual string Given { get; set; }
  public virtual string Middle { get; set; }
  public virtual string Family { get; set; }
}

public class EncryptedColumnConvention
  : AttributePropertyConvention<EncryptedAttribute> {
  protected override void Apply(
    EncryptedAttribute attribute, IPropertyInstance instance)
  {
    var dbType = typeof(EncryptedColumnType<>).MakeGenericType(domainType);
    instance.CustomType(dbType);  
  }
}

public class UserRecordMap : ClassMap<UserRecord> {
  public UserRecordMap() {
    Id(o => o.Id);
    Map(o => o.Username);
    Map(o => o.EmailAddress);
    Map(o => o.DateOfBirth);
    Component(o => o.LegalName).ColumnPrefix("LegalName");
    // etc.
  }
}

public class PersonNameMap : ComponentMap<PersonName> // etc.

如上所示,我试图将这一切与AttributePropertyConvention结合在一起。这适用于简单的属性,例如EmailAddress将获得自定义类型的EncryptedColumnType。

但它不适用于通过组件映射的复杂类型(例如LegalName)的属性。我想要的是加密LegalName的每个属性,因为我用[Encrypted]装饰它。换句话说,我希望UserRecord db表有三个加密 名称字段 - 给定,中间和家庭。

似乎AttributePropertyConvention根本没有应用于LegalName或其任何成员属性。也许我需要使用另一种类型的公约来处理这种情况?

我知道我可以使用[Encrypted]装饰PersonName中的各个属性,而不是在UserRecord中装饰[LegalName]属性。我测试了它,它工作正常。如果有必要,我可以回到这种方法,但我有兴趣尝试让上面的方法概述起作用。

1 个答案:

答案 0 :(得分:0)

跟进,我没有找到直接实现我所描述的方法。根据C#中的属性如何工作,我可以看到很难或不可能实现这样的事情。

相反,我只是将[Encrypted]属性添加到PersonName类的每个属性中,并且始终对生成的数据库表中的PersonName列进行加密。将来,如果我确实需要将PersonName映射为另一个实体的非加密“组件”,我可以使用禁用加密的属性来装饰未加密的类。它的所有映射列/组件,覆盖在该类的属性/组件映射中找到的任何[Encrypted]属性。