如何在运行时检测NHibernate HasManyToMany映射?

时间:2011-11-21 19:10:38

标签: fluent-nhibernate runtime many-to-many

我试图在运行时检测实体中的HasManyToMany关系以进行测试。我编写错误映射的人遇到了很多问题,所以我编写了一个测试来测试我们的持续集成服务器上的每个映射。

现在我可以通过检测映射的Id属性并调用.Get()或复合getter来测试每个实体,复合和非复合。其中大部分是使用反射完成的。我在遍历每个实体类型时使用GetClassMetadata。

但我错过了测试被破坏的东西,HasManyToMany。 我正在使用Fluent NHibernate,映射是:

        mapping.HasManyToMany<ServiceType>(x => x.ServiceTypes)
            .Schema("Marketplace")
            .Table("ListingServiceTypes")
            .ParentKeyColumn("PackageID")
            .ChildKeyColumn("ServiceTypeID")
            .Cascade.SaveUpdate().LazyLoad();

既然没有实体来“测试”这种关系,我不会跑过来。 我需要知道的是如何找到用“HasManyToMany”映射的对象的属性。如果我只能检测到它们,我可以调用它们。

我不想强制延迟加载每个集合,因为如果各个实体的映射是正确的,映射将是,因为我们使用它们的约定。

2 个答案:

答案 0 :(得分:0)

  1. 获取FluentNHibernate的源代码,并复制到您的项目HasManyToManyStep.cs(FluentNHibernate.Automapping.Steps)

  2. 将您的逻辑添加到ShouldMap()方法。 FNH调用此方法检测多对多关系。您可以更改确定多对多关系的方式(例如,通过属性)。在您的情况下,您可能希望通过反射添加一个属性来标记属性...

  3. 用新的步骤替换默认步骤:

    public class MyMappingConfiguration : DefaultAutomappingConfiguration
    {
        public override IEnumerable<IAutomappingStep> GetMappingSteps(AutoMapper mapper, IConventionFinder conventionFinder)
        {
            var steps = base.GetMappingSteps(mapper, conventionFinder);
            var finalSteps = steps.Where(c => c.GetType() != typeof(FluentNHibernate.Automapping.Steps.HasManyToManyStep)).ToList();
            var idx = finalSteps.IndexOf(steps.Where(c => c.GetType() == typeof(PropertyStep)).First());
            finalSteps.Insert(idx + 1, new MyCustomHasManyStep(this));
            return finalSteps; 
        }
    }
    

答案 1 :(得分:0)

今天必须这样做。

var CollectionMetaData = SessionFactory.GetCollectionMetadata(T.FullName + '.' + info.Name);
if (CollectionMetaData is NHibernate.Persister.Collection.BasicCollectionPersister)
{
    if (((NHibernate.Persister.Collection.BasicCollectionPersister)CollectionMetaData).IsManyToMany)
    {
        //Do something.
    }
}

其中T是Type,info是来自T.GetProperties()

的属性信息