我是NHibernate的新手,我想创建一个简单的项目来开始使用它。我按照本教程http://www.youtube.com/watch?v=FkmFI736wMU设置了NHibernate文件和配置。与链接不同,我使用Mysql。 我无法运行该程序,因为我在创建配置对象后立即获得映射异常(无法编译映射文档:catsHibernate.Code.Cat.hbm.xml)。这是我的代码,Cat是一个只有get和sets的简单类。
的App.config
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MySQLDialect</property>
<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
<property name="connection.connection_string">Server=localhost;Database=catsdb;User ID=root;Password=root</property>
<mapping assembly="catsHibernate"/>
</session-factory>
</hibernate-configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
Cat.hbm.xml
<?xml version="1.0"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="catsHibernate.code" namespace="catsHibernate.code">
<class name="Cat" table="cats">
<id name="id" column="id" type="String"></id>
<property name="name" type="String">
<column name="name" length="45" sql-type="varchar" not-null="true"/>
</property>
<property name="sex" column="sex" not-null="true" update="false"/>
<property name="weight" column="weight" not-null="true"/>
</class>
</hibernate-mapping>
Program.cs的
class Program
{
static void Main(string[] args)
{
Configuration cfg = new Configuration().Configure();
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
//ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
ISession session = sessionFactory.OpenSession();
ITransaction tx1 = session.BeginTransaction();
Cat c1 = new Cat();
c1.Id = "cat1";
c1.Name = "Fluffy";
c1.Sex = 'f';
c1.Weight = 3.2F;
Cat c2 = new Cat();
c2.Id = "cat2";
c2.Name = "Mittens";
c2.Sex = 'm';
c2.Weight = 4.3F;
try
{
session.Save(c1);
session.Save(c2);
tx1.Commit();
}
catch (Exception ex)
{
tx1.Rollback();
throw ex;
}
ITransaction tx2 = session.BeginTransaction();
var cats = session.CreateQuery("FROM cats").List<Cat>();
foreach (Cat c in cats)
{
Console.WriteLine(c.Name);
}
tx2.Commit();
session.Close();
}
}
Cat.hbm.xml是嵌入式资源。就像我说的,我在创建配置对象后立即得到映射异常 - &gt;配置cfg = new Configuration()。Configure();
我在这里做错了什么?
编辑 - 堆栈跟踪
NHibernate.MappingException was unhandled
HResult=-2146232832
Message=Could not compile the mapping document: catsHibernate.Code.Cat.hbm.xml
Source=NHibernate
StackTrace:
at NHibernate.Cfg.Configuration.LogAndThrow(Exception exception) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 342
at NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping mappingDocument, String documentFileName) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 530
at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument doc) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 500
at NHibernate.Cfg.Configuration.ProcessMappingsQueue() in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 1865
at NHibernate.Cfg.Configuration.AddDocumentThroughQueue(NamedXmlDocument document) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 1857
at NHibernate.Cfg.Configuration.AddXmlReader(XmlReader hbmReader, String name) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 1850
at NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream, String name) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 652
at NHibernate.Cfg.Configuration.AddResource(String path, Assembly assembly) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 690
at NHibernate.Cfg.Configuration.AddAssembly(Assembly assembly) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 769
at NHibernate.Cfg.Configuration.AddAssembly(String assemblyName) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 752
at NHibernate.Cfg.Configuration.DoConfigure(ISessionFactoryConfiguration factoryConfiguration) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 1574
at NHibernate.Cfg.Configuration.Configure() in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 1433
at catsHibernate.Program.Main(String[] args) in c:\Users\Cátia\Documents\Visual Studio 2012\Projects\catsHibernate\catsHibernate\Code\Program.cs:line 15
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: NHibernate.MappingException
HResult=-2146232832
Message=persistent class catsHibernate.Code.Cat, catsHibernate.Code not found
Source=NHibernate
StackTrace:
at NHibernate.Cfg.XmlHbmBinding.Binder.ClassForFullNameChecked(String fullName, String errorMessage) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\Binder.cs:line 105
at NHibernate.Cfg.XmlHbmBinding.Binder.ClassForNameChecked(String name, Mappings mappings, String errorMessage) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\Binder.cs:line 117
at NHibernate.Cfg.XmlHbmBinding.ClassBinder.BindClass(IEntityMapping classMapping, PersistentClass model, IDictionary`2 inheritedMetas) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\ClassBinder.cs:line 32
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(HbmClass classSchema, IDictionary`2 inheritedMetas) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\RootClassBinder.cs:line 21
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(HbmClass rootClass, IDictionary`2 inheritedMetas) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\MappingRootBinder.cs:line 84
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddEntitiesMappings(HbmMapping mappingSchema, IDictionary`2 inheritedMetas) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\MappingRootBinder.cs:line 42
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(HbmMapping mappingSchema) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\MappingRootBinder.cs:line 31
at NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping mappingDocument, String documentFileName) in p:\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:line 523
InnerException: System.IO.FileNotFoundException
HResult=-2147024894
Message=Could not load file or assembly 'catsHibernate.Code' or one of its dependencies. O sistema não conseguiu localizar o ficheiro especificado.
Source=mscorlib
FileName=catsHibernate.Code
FusionLog==== Pre-bind state information ===
LOG: DisplayName = catsHibernate.Code
(Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: catsHibernate.Code | Domain ID: 1
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/Users/Cátia/documents/visual studio 2012/Projects/catsHibernate/catsHibernate/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : NHibernate, Version=3.3.1.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\Cátia\documents\visual studio 2012\Projects\catsHibernate\catsHibernate\bin\Debug\catsHibernate.vshost.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
StackTrace:
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.Load(String assemblyString)
at NHibernate.Util.ReflectHelper.TypeFromAssembly(AssemblyQualifiedTypeName name, Boolean throwOnError) in p:\nhibernate-core\src\NHibernate\Util\ReflectHelper.cs:line 308
at NHibernate.Util.ReflectHelper.ClassForName(String name) in p:\nhibernate-core\src\NHibernate\Util\ReflectHelper.cs:line 181
at NHibernate.Cfg.XmlHbmBinding.Binder.ClassForFullNameChecked(String fullName, String errorMessage) in p:\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\Binder.cs:line 99
InnerException:
答案 0 :(得分:0)
如果您提供完整的异常跟踪,则可以更轻松地找出问题所在。但可以肯定的是,NHibernate和C#实体命名是区分大小写。上面的代码段不是这种情况
C#代码:
Cat c1 = new Cat();
c1.Id = "cat1";
c1.Name = "Fluffy";
c1.Sex = 'f';
c1.Weight = 3.2F;
...
表明,您的C#实体Cat
具有标准命名,并且应该看起来像(虚拟关键字必不可少)
public class Cat
{
public virtual string Id { get; set; }
public virtual string Name { get; set; }
...
但您的映射是针对小写属性的:
<id name="id" column="id" ...
<property name="name" ..
<property name="sex" ...
<property name="weight" ...
它必须与C#完全相同:
<id name="Id" column="id" type="String" generator="assigned" />
<property name="Name" type="String">
<column name="name" length="45" sql-type="varchar" not-null="true"/>
</property>
<property name="Sex" column="sex" not-null="true" update="false"/>
<property name="Weight" column="weight" not-null="true"/>
答案 1 :(得分:0)
你做错了几件事。您的映射也是错误的 - 属性名称和类不匹配。这是我尝试使用sql server的示例 - 您可以将连接设置更改为mysql。 所以写一个类Cat(属性名称应该是大写但是按照上面的例子)
public class Cat
{
public string id { get; set; }
public string name { get; set; }
public string sex { get; set; }
public decimal weight { get; set; }
}
这是表格:
CREATE TABLE [dbo].[cats](
[id] [varchar](50) NOT NULL,
[name] [varchar](45) NOT NULL,
[sex] [nchar](10) NOT NULL,
[weight] [decimal](18, 0) NOT NULL
)
现在我们创建一个hbm文件(观察映射的属性的名称),类名和程序集名称
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="catsHibernate.code" namespace="catsHibernate.code"> <class name="Cat" table="cats" lazy="false">
<id name="id" column="id" type="String"></id>
<property name="name" type="String">
<column name="name" length="45" sql-type="varchar" not-null="true"/>
</property>
<property name="sex" column="sex" not-null="true" update="false"/>
<property name="weight" column="weight" not-null="true"/>
这是连接的配置文件(观察程序集名称):
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Data Source=.\sqlexpress;Database=StackExchangeExample;Integrated Security=SSPI;</property>
<mapping assembly="catsHibernate.code"/>
</session-factory>
现在你的程序应该运行(在查询中查看类的名称)
private static void Main(string[] args)
{
var cfg = new Configuration();
cfg.Configure();
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
ISession session = sessionFactory.OpenSession();
ITransaction tx1 = session.BeginTransaction();
var c1 = new Cat();
c1.id = "cat1";
c1.name = "Fluffy";
c1.sex = "f";
c1.weight = new Decimal(3.2);
var c2 = new Cat();
c2.id = "cat2";
c2.name = "Mittens";
c2.sex = "m";
c2.weight = new Decimal(4.3);
try
{
session.Save(c1);
session.Save(c2);
tx1.Commit();
}
catch (Exception ex)
{
tx1.Rollback();
throw ex;
}
ITransaction tx2 = session.BeginTransaction();
IList<Cat> cats = session.CreateQuery("FROM Cat").List<Cat>();
foreach (Cat c in cats)
{
Console.WriteLine(c.name);
}
tx2.Commit();
session.Close();
}