本文介绍了NHibernate映射错误([EntityName]未映射)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目(c#,nhibernate,npgsql,nlog)有一个名为Entry的实体,应映射到名为test的数据库表.该表包含一些测试条目.

My project (c#, nhibernate, npgsql, nlog) has one entity named Entry and should be mapped to the database table named test. Table contains some test entries.

我的应用程序代码如下:

My application code is as follows:

public void work()
{
    ISessionFactory sessions = new Configuration().Configure().BuildSessionFactory();
    ISession session = sessions.OpenSession();

    IList<Entry> entries = session.CreateQuery("from Entry").List<Entry>();

    foreach (Entry e in entries)
    {
        logger.Debug("Entry: " + e.id + " with " + e.name);
    }
}

Entry实体如下所示:

namespace pgsql
{
    class Entry
    {
        public virtual int id { get; set; }
        public virtual string name { get; set; }
    }
}

我的NHibernate配置的结构如下:

My NHibernate configuration is structured as below:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
        <property name="connection.driver_class">NHibernate.Driver.NpgsqlDriver</property>
        <property name="dialect">NHibernate.Dialect.PostgreSQLDialect</property>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="default_catalog">test</property>
        <property name="default_schema">test</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="connection.connection_string">server=localhost;database=*****;uid=*****;pwd=*****;</property>
    </session-factory>
</hibernate-configuration>

Entry实体配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping schema="test" xmlns="urn:nhibernate-mapping-2.2">
    <class name="Entry" table="test">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
    </class>
</hibernate-mapping>

这引发以下错误:

我已确保Visual Studio将所有hbm.xml文件复制到输出目录.我想念什么?

I have made sure, that Visual Studio is copying all hbm.xml files to the output directory. What am i missing?

推荐答案

根据您的回答进行

ISessionFactory sessions = new Configuration().Configure().AddAssembly(Assembly.GetExecutingAssembly()).BuildSessionFactory();

但是我仍然不知道,为什么它必须是那样.

but i still don't know, why it has to be like that.

我将解释为什么必须这样.

I will explain why it has to be like that.

您的实体在与应用程序相同的程序集中定义.
当您调用Configuration().Configure().BuildSessionFactory()时,实际上所有的HBM文件都将被忽略.您需要执行以下任一操作才能将HBM文件添加到Configuration实例:

Your entity is defined in same assembly as that of your application.
When you call Configuration().Configure().BuildSessionFactory(), actually all your HBM files are being ignored. You need to do either of following to add HBM file to Configuration instance:

  • 对每个单独的HBM文件使用new Configuration().AddFile("MyFile.hbm.xml").
  • 使用new Configuration().Configure().AddAssembly(YourAssembly())告诉NHibernate 查找所有HBM文件并为您添加所有这些文件.
  • 下面链接的文档中提到的其他方式.
  • Use new Configuration().AddFile("MyFile.hbm.xml") for each individual HBM file.
  • Use new Configuration().Configure().AddAssembly(YourAssembly()) to tell NHibernate to look for all HBM files and add all those for you.
  • Other ways mentioned in document linked below.

由于您既没有执行任何操作,也没有将实体配置添加到Configuration.乳清您尝试运行HQL查询时,NHibernate正在寻找未定义的Entry实体(已添加到Configuration中).因此就是错误.

As you was not doing either of this, there were no entity configurations added to Configuration. Whey you try to run your HQL query, NHibernate was looking for Entry entity which was not defined (added to Configuration). Hence was the error.

正如您在回答中提到的那样,您选择了第二种方法将HBM文件添加到Configuration而问题消失了.

As you mentioned in your answer, you choose second way to add HBM files to Configuration and issue went away.

Configuration cfg = new Configuration()
.AddAssembly( "NHibernate.Auction" );

然后,NHibernate将在程序集中查找以.hbm.xml结尾的任何资源.这种方法消除了任何硬编码的文件名,并确保在程序集中添加了映射文件.

Then NHibernate will look through the assembly for any resources that end with .hbm.xml. This approach eliminates any hardcoded filenames and ensures the mapping files in the assembly get added.

有关更多详细信息,请参考 doc .

Please refer doc for more details.

实体名称也应包括名称空间.

Entity name should include namespace as well.

IList<Entry> entries = session.CreateQuery("from pgsql.Entry").List<Entry>();

为了简化重构,您还可以更改为以下内容:

To make refactoring bit easy, you may also change to something like following:

var queryString = string.Format("from {0}", typeof(Entry));
IList<Entry> entries = session.CreateQuery(queryString).List<Entry>();

请参阅 14.2部分.来自 docs 的from子句.

Please refer section 14.2. The from clause from docs.

这不是问题的一部分,但致电BuildSessionFactory的成本很高.您不需要重复它.您可以在应用程序启动时调用它,并维护ISessionFactory的实例以供将来使用.

Not a part of your problem but, call to BuildSessionFactory is costly. You do not need to repeat it. You can call it at the startup of your application may be and maintain the instance of ISessionFactory for future use.

这篇关于NHibernate映射错误([EntityName]未映射)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 10:29