Skip to main content
 首页 » 编程设计

c#之FluentNHibernate base ClassMapT> 并避免使用 typeof(T) 来确定用于定义 NHibernate 生成器的实体 ID 类型

2024年01月11日36linjiqin

为了集中我的每个 FluentNHibernate 类映射的一些逻辑(特别是用于映射审计属性和实际主 ID),我有一个名为 AuditedEntityClassMap 的基本 ClassMap,它类似于以下内容:

public class AuditedEntityClassMap<TEntity, T> : ClassMap<TEntity> where TEntity : AuditedPersistentObject<T> 
{ 
    public AuditedEntityClassMap() 
    { 
        Cache.ReadWrite(); 
        DynamicUpdate(); 
        ApplyId(); 
        this.ChangeAuditInfo(); 
    } 
 
    protected virtual void ApplyId() 
    { 
            if (typeof(T) == typeof(int)) 
                map.Id(x => x.Id).GeneratedBy.HiLo(HiLoConstants.NHibernateHiLoTable, HiLoConstants.NHibernateHiLoColumn, HiLoConstants.NHibernateHiLoMaxLo); 
            else if (typeof(T) == typeof(Guid)) 
                map.Id(x => x.Id).GeneratedBy.GuidComb(); 
            else 
                throw new InvalidIdTypeInClassMappingException("Invalid type set in class mapping: " + typeof(T)); 
    } 
} 

我的问题是,为了确定应该用于它的 NHibernate 生成器映射的类型而进行的泛型类型检查有异味,我想知道是否有更好的方法来处理它。

  1. 我的域实体的 ID 的通用类型在整个过程中都得到了使用,并且在其他任何地方都很好用(并且被广泛使用)。
  2. 如果可以避免,我宁愿不必在每个实体的 ClassMap 中定义 ID 映射。如果这是这样做的唯一方法,我会接受它。

想法和建议?

请您参考如下方法:

我无法编译您的代码,但我很惊讶它能工作。

T 不是数据类而不是 id。

我能想到的另一种方法是反射(reflection),但我无法想象这是更好的方法。

您可以通过反射获取 T 的属性并搜索名为 Id 或 id 的属性。 然后获取该属性的类型。但我不知道在这种情况下您将如何调用 Map。

var pp = typeof(T).GetProperties().Where(p => p.Name == "Id").FirstOrDefault(); 
if (pp != null) 
{ 
  if (pp.PropertyType.Name == "Int64" || pp.PropertyType.Name == "Int32") 
  { 
    Map(); 
  } 
}