2014-06-09 91 views
0

我是NHibernate的新手,我想創建一個簡單的項目來開始使用它。我按照這個教程http://www.youtube.com/watch?v=FkmFI736wMU來設置NHibernate文件和配置。與鏈接不同,我使用Mysql。 我無法運行該程序,因爲我一創建配置對象就立即得到一個映射異常(無法編譯映射文檔:catsHibernate.Code.Cat.hbm.xml)。這是我的代碼,貓是一個簡單的類,只有獲取和設置。C#NHibernate MappingException未處理

的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嵌入資源。就像我所說的,只要創建一個配置對象 - >配置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

你代碼無法正確找到類 - 已經把完整的例子下面。上面的錯誤消息=持久類catsHibernate.Code.Cat,catsHibernate.Code找不到 – Avneesh

回答

0

你已經做了幾件事情是錯誤的。您的映射也是錯誤的 - 屬性和類名稱不匹配。這是我用sql server試過的例子 - 你可以將連接設置改爲mysql。 所以寫一個類貓(屬性名應該是大寫的,但下面你上面的例子)

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(); 
    } 
+0

hbm文件在屬性中設置爲Embedded Resource。當您從session.query(「」)創建查詢時,名稱是區分大小寫的類名稱 – Avneesh

+0

嗨,我現在可以添加兩個貓。我的Cat.cs文件看起來像你的,除非我保留char和float類型。我將lazy =「false」添加到xml文件以避免使用虛擬類型。我也改變了你寫的查詢。 我覺得奇怪的是,我不得不將每個命名空間和程序集都改爲catsHibernate,即使我的項目中有文件夾。我應該在名稱空間和程序集中編寫catsHibernate.Code,但是如果我這樣寫,我會得到映射異常。這裏有什麼問題? – user3641702

+0

您沒有 - 在映射文件中,您已獲得了程序集名稱和名稱空間名稱。然後,您可以爲每個hbm文件設置不同的命名空間,例如namespace =「catsHibernate.code.MyNamespace」,或者忘記命名空間屬性並定義完整的類名稱,包括類映射中的命名空間。在會話查詢中使用像這樣的「from」+ typeof(Cat),這會正確拾取。 – Avneesh

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"/> 
+0

嗨,我添加了上面的堆棧跟蹤。我試圖改變像你解釋的屬性,但我仍然得到映射異常。 – user3641702