在Fluent Nhibernate中自动映射复合元素

在Fluent Nhibernate中自动映射复合元素,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我试图让自动持久性模型映射几个复合元素。然而,似乎要么我最终将其映射为一个实体,要么我将其降级为手动映射,要么它根本不起作用。下面的一些代码演示了我的问题: using System; using System.Collections.Generic; using FluentNHibernate.AutoMap; using FluentNHibernate.Cfg; using FluentNHibernate.Conventions.Helpers; using NHibernate.Cf

我试图让自动持久性模型映射几个复合元素。然而,似乎要么我最终将其映射为一个实体,要么我将其降级为手动映射,要么它根本不起作用。下面的一些代码演示了我的问题:

using System;
using System.Collections.Generic;
using FluentNHibernate.AutoMap;
using FluentNHibernate.Cfg;
using FluentNHibernate.Conventions.Helpers;
using NHibernate.Cfg;

namespace Scanner {
    public class Root {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Component> Components { get; set; }
    }

    public class Component {
        public string Name { get; set; }
    }

    class Example {
        public void DoesntGetComponents()
        {
            Configuration configuration = new Configuration();
            configuration.SetProperty("ConnectionString", "");
            configuration.SetProperty("dialect", "NHibernate.Dialect.MsSql2005Dialect");
            var config = Fluently.Configure(configuration)
                .Mappings(m => m.AutoMappings.Add(AutoMapping))
                .BuildConfiguration();
            var sql2005 = new NHibernate.Dialect.MsSql2005Dialect();
            foreach (var line in config.GenerateSchemaCreationScript(sql2005))
            {
                Console.WriteLine(line);
            }
        }

        static AutoPersistenceModel AutoMapping() {
            AutoPersistenceModel model = new AutoPersistenceModel();
            return model
                .AddEntityAssembly(typeof(Root).Assembly)
                .WithSetup(e => e.IsComponentType = t => t == typeof(Component))
                .Where(t => t == typeof(Root))
                .MergeWithAutoMapsFromAssemblyOf<Root>()
                .ConventionDiscovery.Add(ForeignKey.Format((p, t) => (p == null ? t.Name : p.Name) + "Id"))
                .ConventionDiscovery.Add(Table.Is(t => t.EntityType.Name))
            ;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用FluentNHibernate.AutoMap;
使用FluentNHibernate.Cfg;
使用FluentNHibernate.Conventions.Helpers;
使用NHibernate.Cfg;
名称空间扫描程序{
公共类根{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection组件{get;set;}
}
公共类组件{
公共字符串名称{get;set;}
}
课例{
public void DoesntGetComponents()
{
配置=新配置();
SetProperty(“ConnectionString”和“”);
SetProperty(“方言”,“NHibernate.dialogue.mssql2005dialogue”);
var config=fluntly.Configure(配置)
.Mappings(m=>m.AutoMappings.Add(自动映射))
.BuildConfiguration();
var sql2005=新的NHibernate.dialogue.mssql2005dialogue();
foreach(config.GenerateSchemaCreationScript(sql2005)中的var行)
{
控制台写入线(行);
}
}
静态自动持久性模型自动映射(){
AutoPersistenceModel=新的AutoPersistenceModel();
回归模型
.AddEntityAssembly(typeof(Root).Assembly)
.with设置(e=>e.IsComponentType=t=>t==typeof(组件))
.其中(t=>t==typeof(根))
.MergeWithAutoMapsFromAssemblyOf()
.ConventionDiscovery.Add(ForeignKey.Format((p,t)=>(p==null?t.Name:p.Name)+“Id”))
.ConventionDiscovery.Add(Table.Is(t=>t.EntityType.Name))
;
}
}
}
(抱歉,太长了,但这是演示问题所需的最少代码。此特定版本的代码根本无法注册组件类型


那么,我做错了什么?

组件本身似乎不是问题所在,而是组件集合的映射。如果您将组件直接映射到根类,这将不会有任何问题

一种可能的解决方法是将组件类设置为实体(添加ID)并覆盖组件到级联+自动删除孤立项的映射:

AutoPersistenceModel
.ForTypesThatDeriveFrom<Root>(map => map.HasMany(root => root.Components).Cascade.AllDeleteOrphan())
AutoPersistenceModel
.ForTypesThatDeriveFrom(map=>map.HasMany(root=>root.Components).Cascade.AllDeleteOrphan())

组件本身似乎不是问题所在,而是组件集合的映射。如果您将组件直接映射到根类,这不会有任何问题

一种可能的解决方法是将组件类设置为实体(添加ID)并覆盖组件到级联+自动删除孤立项的映射:

AutoPersistenceModel
.ForTypesThatDeriveFrom<Root>(map => map.HasMany(root => root.Components).Cascade.AllDeleteOrphan())
AutoPersistenceModel
.ForTypesThatDeriveFrom(map=>map.HasMany(root=>root.Components).Cascade.AllDeleteOrphan())

我希望能够结束这个问题,因为它不再相关。我不相信任何新的工作会使用FNH,因为NH有类似的功能。NH的当前版本(我写这篇文章时是3.2版)仍然没有自动映射一个la FNH,这是继续使用FNH的一个很好的理由,我的观点是。我认为大多数自动映射实际上更容易由自己实现,而不是试图让别人的系统工作。在我放弃FNH之前,我放弃了FNH自动映射很长一段时间。嗯…我的经验是FNH自动映射在我的greenfield项目中工作得很好,有一个相当复杂的对象模型。此外,我在FNH和NH的“代码映射”中看到了很多这样的问题,适用于我知道自动映射将毫不费力地处理的情况。您遇到了什么样的问题?我怀疑答案是我没有处理任何类似于greenfield的事情。ID约定、异常处理等都比编写遵循代码,只是在它们不适用时不调用它们。我希望能够结束这个问题,因为它不再相关。我不相信任何新的工作会使用FNH,因为NH有类似的功能。NH的当前版本(我写这篇文章时为3.2)仍然没有自动映射一个la FNH,这是继续使用FNH的一个很好的理由,我的观点是。我认为大多数自动映射实际上更容易由自己实现,而不是试图让别人的系统工作。在我放弃FNH之前,我放弃了FNH自动映射很长一段时间。嗯…我的经验是FNH自动映射在我的greenfield项目中工作得很好,有一个相当复杂的对象模型。此外,我在FNH和NH的“代码映射”中看到了很多这样的问题,适用于我知道自动映射将毫不费力地处理的情况。您遇到了什么样的问题?我怀疑答案是我没有处理任何类似于greenfield的事情。ID约定、异常处理等都比编写遵循当代码不适用时,不要调用它们。