我的项目(c#,nhibernate,npgsql,nlog)有一个名为Entry
的实体,应映射到名为test
的数据库表。该表包含一些测试条目。
我的应用程序代码如下:
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配置的结构如下:
<?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>
这引发以下错误:
未从[条目]映射条目[p]
我已经确定Visual Studio会将所有hbm.xml
文件复制到输出目录。我想念什么?
答案 0 :(得分:1)
根据您的回答进行编辑:
解决方案是使用Assembly进行初始化
ISessionFactory sessions = new Configuration().Configure().AddAssembly(Assembly.GetExecutingAssembly()).BuildSessionFactory();
但是我仍然不知道,为什么它必须是那样。
我将解释为什么必须这样。
您的实体与应用程序在同一程序集中定义。
当您调用Configuration().Configure().BuildSessionFactory()
时,实际上所有的HBM文件都将被忽略。您需要执行以下任一操作,才能将HBM文件添加到Configuration
实例中:
new Configuration().AddFile("MyFile.hbm.xml")
。new Configuration().Configure().AddAssembly(YourAssembly())
告诉NHibernate 查找所有HBM文件并为您添加所有这些文件。由于您既没有执行任何操作,也没有向Configuration
添加任何实体配置。乳清您尝试运行HQL查询时,NHibernate正在寻找未定义的Entry
实体(已添加到Configuration
中)。因此就是错误。
正如您在回答中提到的那样,您选择了第二种方法将HBM文件添加到Configuration
并解决了问题。
另一种替代方法(可能是最好的)是让NHibernate加载Assembly中包含的所有映射文件:
Configuration cfg = new Configuration() .AddAssembly( "NHibernate.Auction" );
然后,NHibernate将在程序集中查找以.hbm.xml结尾的任何资源。这种方法消除了任何硬编码的文件名,并确保在程序集中添加了映射文件。
有关更多详细信息,请参阅doc。
实体名称也应包括名称空间。
IList<Entry> entries = session.CreateQuery("from pgsql.Entry").List<Entry>();
为了简化重构,您还可以更改为以下内容:
var queryString = string.Format("from {0}", typeof(Entry));
IList<Entry> entries = session.CreateQuery(queryString).List<Entry>();
请参考 14.2节。来自docs的from子句。
这不是问题的一部分,但致电BuildSessionFactory
的费用很高。您不需要重复它。您可以在应用程序启动时调用它,并维护ISessionFactory
的实例以供将来使用。
答案 1 :(得分:1)
解决方案是使用Assembly进行初始化
ISessionFactory sessions = new Configuration().Configure().AddAssembly(Assembly.GetExecutingAssembly()).BuildSessionFactory();
但是我仍然不知道,为什么它必须是那样。