C#NHibernate MappingException未处理

时间:2014-06-09 17:07:56

标签: c# nhibernate

我是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: 

2 个答案:

答案 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();
    }