【问题标题】:How can I detect NHibernate HasManyToMany mapping at run-time?如何在运行时检测 NHibernate HasManyToMany 映射?
【发布时间】:2012-01-03 06:26:05
【问题描述】:

我试图在运行时检测实体中的 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”映射的对象的属性。如果我能检测到它们,我可以很好地调用它们。

我不想强制延迟加载每个集合,因为如果单个实体的映射正确,那么映射就会正确,因为我们对它们使用约定。

【问题讨论】:

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


    【解决方案1】:
    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; 
          }
      }
      

    【讨论】:

      【解决方案2】:

      今天必须这样做。

      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() 的属性信息

      【讨论】:

        猜你喜欢
        • 2010-11-22
        • 1970-01-01
        • 2012-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多