流畅的NHibernate自动化无法正常工作

时间:2010-11-10 20:29:26

标签: .net nhibernate fluent-nhibernate

我遇到了Fluent NHibernate的问题,其中自动化没有在我的Web项目DLL中获取权限。通常我将所有实体存储在一个单独的程序集中,这一直都有效。但是,这个项目相当小,所以我试图将它全部保存在一个项目中。但是,当我调用AutoMap.AssemblyOf<MyEntityType>()时,不会创建映射。我想知道这是否是因为该实体存在于从临时ASP.NET文件文件夹加载的Web项目程序集中,而不是项目所在的实际文件夹。是权限问题还是什么?我不知道从哪里开始调试......

示例实体:

namespace MyProject.Entities 
{
    public class Letter : EntityBase
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Company { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
        public string Country { get; set; }
        public string Interest { get; set; }
        public string Section1 { get; set; }
        public string Section2 { get; set; }
        public string Section3 { get; set; }
        public string LetterText { get; set; }
        public int StepNumber { get; set; }
    }
}    

相关的推特代码:

   private static ISessionFactory GetSessionFactory()
    {
        var database = MsSqlConfiguration.MsSql2005
            .ConnectionString(Configuration.ConnectionString)
            .DefaultSchema(DEFAULT_SCHEMA)
            .AdoNetBatchSize(BATCH_SIZE);

        var mappings = AutoMap.AssemblyOf<Letter>()
            .Where(x => x.GetType() == typeof(Letter))
            .Conventions.Add
            (
                ConventionBuilder.Id.Always(x =>
                    x.GeneratedBy.HiLo(HILO_TABLE, HILO_COLUMN, HILO_MAX_LO)),
                ConventionBuilder.HasMany.Always(x => x.Cascade.AllDeleteOrphan()),
                Table.Is(o => Inflector.Pluralize(o.EntityType.Name)),
                PrimaryKey.Name.Is(o => "Id"),
                ForeignKey.EndsWith("Id"),
                DefaultLazy.Never(),
                DefaultCascade.All()
            );

        // ...

我更改了Where子句以查找特定类型而不是命名空间,但这也不起作用。映射对象仍然是空的。

此外,EntityBase类是一个空类,但是对于一个由所有实体继承的属性“Id”。

编辑:我将实体移动到他们自己的程序集中并且仍然遇到问题,因此它与Web项目程序集的位置无关。我还是很遗憾。 :(

4 个答案:

答案 0 :(得分:2)

我发现了问题。我从EntityBase继承但没有IgnoreBase调用。我假设因为EntityBase不在命名空间中我有资格获得我不需要它的映射,但显然,如果你没有明确地忽略基类,即使它是另一个命名空间,映射也会失败。

新的引导代码如下所示:

private static ISessionFactory GetSessionFactory()
{
    var database = MsSqlConfiguration.MsSql2005
        .ConnectionString(Configuration.ConnectionString)
        .DefaultSchema(DEFAULT_SCHEMA)
        .AdoNetBatchSize(BATCH_SIZE);

    var mappings = AutoMap.AssemblyOf<Letter>()
        .Where(x => x.GetType() == typeof(Letter))
        .IgnoreBase<EntityBase>()
        .Conventions.Add
        (
            ConventionBuilder.Id.Always(x =>
                x.GeneratedBy.HiLo(HILO_TABLE, HILO_COLUMN, HILO_MAX_LO)),
            ConventionBuilder.HasMany.Always(x => x.Cascade.AllDeleteOrphan()),
            Table.Is(o => Inflector.Pluralize(o.EntityType.Name)),
            PrimaryKey.Name.Is(o => "Id"),
            ForeignKey.EndsWith("Id"),
            DefaultLazy.Never(),
            DefaultCascade.All()
        );

    // ...

答案 1 :(得分:0)

试试这个,让我知道会发生什么:

var config = Fluently.Configure()
    .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Letter>()
        .Where(n => n.Name == "Letter"))
        .ExportTo(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + "/mappings"))
    .BuildConfiguration();

var factory = config.BuildSessionFactory();

我完全没有通知的猜测是你没有调用BuildConfiguration(),所以NHibernate没有打扰创建映射。

答案 2 :(得分:0)

我创建了一个新的 ASP.NET MVC 应用程序并添加了这两个类和这个配置:

public abstract class Entity
{
    public int Id { get; set; }
}

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

// this is in Global.asax
protected void Application_Start()
{
    Fluently.Configure()
        .Database(SQLiteConfiguration.Standard.InMemory())
        .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Entity>()
            .Where(t => t.IsSubclassOf(typeof (Entity))))
            .ExportTo(*the desktop*))
        .BuildConfiguration();
}

此代码能够成功导出映射。

修改

刚看到你的答案。不确定为什么要IgnoreBase()解决问题。这应该只确定如何为子类策略映射基类。哦,好吧。

答案 3 :(得分:0)

我发现域类需要在一个单独的程序集中,而不是构建ISessionFactory的代码。将域对象移动到单独的程序集后,一切都应该正常工作。

出于好奇,我尝试了Conventions.Add从上面的想法,它永远不会工作。意思是,我可以使用这样的域类:

public class Person
    {
        public virtual int Id { get; private set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
    }

使用如下所示的AutoMapping例程:

public NHibernate.ISessionFactory Create()
        {
            var persistenceModel =
                AutoMap
                    .AssemblyOf<Person>();

            var ret =
                Fluently
                    .Configure()
                    .Database(MsSqlCeConfiguration.Standard.ShowSql().FormatSql().ConnectionString(ex => ex.FromConnectionStringWithKey("PersonSqlCe")))
                    .Mappings(x => x.AutoMappings.Add(persistenceModel))
                    .ExposeConfiguration(config =>
                        {
                            new SchemaExport(config).Create(true, true);

                            // DOC: workaround for identity column failures in SQLCE
                            config.SetProperty("connection.release_mode", "on_close");
                        })
                    .BuildSessionFactory();

            return ret;
        }

一切正常。但是,当我将我的域类更改为如下所示:

public class Person
    {
        public virtual int BAD { get; private set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
    }

并更改我的AutoMapping例程以符合新的PrimaryKey属性名称期望,例如下面的代码:

public NHibernate.ISessionFactory Create()
        {
            var persistenceModel =
                AutoMap
                    .AssemblyOf<Person>();

            persistenceModel.Conventions.Add(PrimaryKey.Name.Is(x => "BAD"));

            var ret =
                Fluently
                    .Configure()
                    .Database(MsSqlCeConfiguration.Standard.ShowSql().FormatSql().ConnectionString(ex => ex.FromConnectionStringWithKey("PersonSqlCe")))
                    .Mappings(x => x.AutoMappings.Add(persistenceModel))
                    .ExposeConfiguration(config =>
                        {
                            new SchemaExport(config).Create(true, true);

                            // DOC: workaround for identity column failures in SQLCE
                            config.SetProperty("connection.release_mode", "on_close");
                        })
                    .BuildSessionFactory();

            return ret;
        }

...我收到如下错误:

  ----> FluentNHibernate.Visitors.ValidationException : The entity 'Person' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id).
    at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory()
    SampleImplementation.cs(28,0): at NHQS.Tests.PersonSampleSessionFactoryCreator.Create()
    SessionFactoryTests.cs(16,0): at

是什么给出的?似乎会议方法没有布线?