Fluent NHibernate:将属性应用于通过组件映射的属性的所有成员
我正在使用Fluent NHibernate(1.2),并且正在致力于实现列级加密。我有一个处理加密的自定义类型,因此域模型可以有原生的明文数据类型(简单字符串、int、datetime等),所有的加密/解密工作都在幕后进行 我希望通过属性指定每个域模型中要加密的属性,并使用约定指定这些属性的自定义类型,以便域模型是良好的POCO,而不提及自定义类型:Fluent NHibernate:将属性应用于通过组件映射的属性的所有成员,nhibernate,fluent-nhibernate,nhibernate-mapping,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,我正在使用Fluent NHibernate(1.2),并且正在致力于实现列级加密。我有一个处理加密的自定义类型,因此域模型可以有原生的明文数据类型(简单字符串、int、datetime等),所有的加密/解密工作都在幕后进行 我希望通过属性指定每个域模型中要加密的属性,并使用约定指定这些属性的自定义类型,以便域模型是良好的POCO,而不提及自定义类型: public class EncryptedAttribute : Attribute {} public class UserRecord
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.
公共类EncryptedAttribute:属性{}
公共类用户记录{
公共虚拟Guid Id{get;set;}
公共虚拟字符串用户名{get;set;}
[加密]
公共虚拟字符串EmailAddress{get;set;}
[加密]
公共虚拟日期时间出生日期{get;set;}
[加密]
公共虚拟人名LegalName{get;set;}
//等等。
}
公共类人名{
给定的公共虚拟字符串{get;set;}
公共虚拟字符串中间{get;set;}
公共虚拟字符串族{get;set;}
}
公共类EncryptedColumn约定
:AttributePropertyConvention{
受保护的覆盖无效应用(
EncryptedAttribute属性,IPropertyInstance)
{
var dbType=typeof(EncryptedColumnType).MakeGenericType(domainType);
CustomType(dbType);
}
}
公共类UserRecordMap:ClassMap{
公共UserRecordMap(){
Id(o=>o.Id);
映射(o=>o.Username);
Map(o=>o.EmailAddress);
Map(o=>o.DateOfBirth);
组件(o=>o.LegalName).ColumnPrefix(“LegalName”);
//等等。
}
}
公共类PersonNameMap:ComponentMap//etc。
如上所示,我正试图将这一切与AttributePropertyConvention联系起来。这适用于简单属性,例如EmailAddress将获得一个自定义类型EncryptedColumnType
但它不适用于通过组件映射的复杂类型(如LegalName)的属性。我想要的是加密LegalName的每个属性,因为我用[Encrypted]修饰它。换句话说,我希望UserRecord db表有三个加密的
名称字段——给定、中间和族
似乎AttributePropertyConvention根本没有应用于LegalName或其任何成员属性。也许我需要用另一种约定来处理这个案子
我知道我可以用[Encrypted]装饰PersonName中的各个属性,而不是装饰UserRecord中的[LegalName]属性。我测试了这个,效果很好。如果有必要,我可以回到这种方法上来,但我有兴趣尝试让上面的方法大纲起作用。接下来,我没有找到直接实现我描述的方法。根据C#中属性的工作方式,我可以看出实现这样的东西是困难的或不可能的
相反,我只是将
[Encrypted]
属性添加到PersonName
类的每个属性中,并始终对结果数据库表中的PersonName
列进行加密。将来,如果我确实需要将PersonName
映射为另一个实体的非加密“组件”,我可能会使用一个属性来修饰非加密类,该属性禁用其所有映射列/组件的加密,覆盖任何[加密]
在该类的属性/组件映射中找到属性。接下来,我没有找到直接实现我所描述内容的方法。根据C#中属性的工作方式,我可以看出实现这样的东西是困难的或不可能的
相反,我只是将[Encrypted]
属性添加到PersonName
类的每个属性中,并始终对结果数据库表中的PersonName
列进行加密。将来,如果我确实需要将PersonName
映射为另一个实体的非加密“组件”,我可能会使用一个属性来装饰非加密类,该属性禁用其所有映射列/组件的加密,覆盖该类的属性/组件映射中找到的任何[encrypted]
属性