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

发布于 2024-12-17 10:17:33 字数 738 浏览 0 评论 0原文

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

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

I am trying to detect HasManyToMany relationships in entities at run-time for testing purposes. I've had many problems with people writing bad mappings so I wrote a test to test every single mapping on our continuous integration server.

Right now I can test every entity, composite and non-composite by detecting the mapped Id property(s) and calling .Get() or a composite getter. Most of which is done using reflection. I am using GetClassMetadata while going over every entity type.

But I missed testing something that was broken, a HasManyToMany.
I am using Fluent NHibernate, and the mapping is:

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

Now since there is no entity to "test" this relationship with, I do not run over it.
What I need to know is how can I find the properties of an object that are mapped with "HasManyToMany". I can invoke them just fine, if I could only detect them.

I do not want to have to force lazy loading of every collection because if the mapping for the individual entities are correct, the mappings will be, because we use conventions for them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鹿港巷口少年归 2024-12-24 10:17:33
  1. 获取FluentNHibernate的源代码,并复制到您的项目HasManyToManyStep.cs (FluentNHibernate.Automapping.Steps)

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

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

    公共类 MyMappingConfiguration :DefaultAutomappingConfiguration
    {
        公共覆盖 IEnumerable; GetMappingSteps(AutoMapper映射器,IConventionFinder conventionFinder)
        {
            var 步骤 = 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));
            返回最终步骤; 
        }
    }
    
  1. Get the source code of FluentNHibernate, and copy to your project HasManyToManyStep.cs (FluentNHibernate.Automapping.Steps)

  2. Add your logic to ShouldMap() method. This method is called by FNH to detect Many To Many relations. You can alter the way many to many relations are determined (for example by an attribute). In your case you want probably add a an attribute by reflection to tag the properties...

  3. Replace the default step with your new one :

    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; 
        }
    }
    
吃→可爱长大的 2024-12-24 10:17:33

今天不得不做这件事。

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 是类型,info 是来自 T.GetProperties() 的属性信息

Had to do this today.

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

where T is the Type and info is the property info from T.GetProperties()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文