我正在使用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]属性。我测试了它,它工作正常。如果有必要,我可以回到这种方法,但我有兴趣尝试让上面的方法概述起作用。
答案 0 :(得分:0)
跟进,我没有找到直接实现我所描述的方法。根据C#中的属性如何工作,我可以看到很难或不可能实现这样的事情。
相反,我只是将[Encrypted]
属性添加到PersonName
类的每个属性中,并且始终对生成的数据库表中的PersonName
列进行加密。将来,如果我确实需要将PersonName
映射为另一个实体的非加密“组件”,我可以使用禁用加密的属性来装饰未加密的类。它的所有映射列/组件,覆盖在该类的属性/组件映射中找到的任何[Encrypted]
属性。