首页 > 解决方案 > 如何为 NHibertnateSession.cs 添加第二个映射 xml?

问题描述

背景:
我有两个表,分别是“产品”和“员工”。

我可以从员工那里检索数据。下一阶段是使用相同的方法,但这次是针对“产品”。

问题:
对于文件“Product.hbm.xml”,应该在 NHibertnateSession.cs 类中应用什么代码?

我今天拥有的代码仅适用于 NHibertnateSession.cs 类中的单个 .hbm.xml

信息:
*我已从 // https://www.dotnetjalps.com/2013/09/asp-net-mvc-nhibernate-crud-getting-started.html检索基本指令

*您还需要考虑到我将来需要应用更多表(.hbm.xml)。

谢谢!


休眠.cfg.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">
      NHibernate.Connection.DriverConnectionProvider
    </property>
    <property name="connection.driver_class">
      NHibernate.Driver.SqlClientDriver
    </property>
    <property name="connection.connection_string">
      Server=fffff-PC\MSSQL2017DEV;database=BookStoreDB;Integrated Security=SSPI;
    </property>
    <property name="dialect">
      NHibernate.Dialect.MsSql2012Dialect
    </property>
  </session-factory>
</hibernate-configuration>

NHibertnateSession.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NHibernate;
using NHibernate.Cfg;

namespace Swinkaran.Nhbnt.Web.Models
{
    public class NHibertnateSession
    {
        public static ISession OpenSession()
        {

            var configuration = new Configuration();
            var configurationPath = HttpContext.Current.Server.MapPath(@"~\Models\hibernate.cfg.xml");
            configuration.Configure(configurationPath);
            var employeeConfigurationFile = HttpContext.Current.Server.MapPath(@"\Mappings\Employee.hbm.xml");

            configuration.AddFile(employeeConfigurationFile);
            ISessionFactory sessionFactory = configuration.BuildSessionFactory();
            return sessionFactory.OpenSession();

        }
    }
}

员工.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Swinkaran.Nhbnt.Web.Models
{
    public class Employee
    {
        public virtual int Id { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string Designation { get; set; }
    }
}

员工.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="Swinkaran.Nhbnt.Web" namespace="Swinkaran.Nhbnt.Web.Models">
  <class name="Employee" table="Employee" dynamic-update="true" >
    <cache usage="read-write"/>
    <id name="Id" column="Id" type="int">
      <generator class="native" />
    </id>
    <property name="FirstName" />
    <property name="LastName" />
    <property name="Designation" />
  </class>
</hibernate-mapping>

家庭控制器

        using (NHibernate.ISession session = NHibertnateSession.OpenSession())
        {
            var employees = session.Query<Employee>().ToList();
        }

USE [BookStoreDB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Product](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
    [Description] [varchar](50) NULL,
PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

标签: c#nhibernatevisual-studio-2017

解决方案


为此,我们按以下方式进行:

  1. 将文件的属性设置Build Action*.hbm.xmlEmbedded Resource
  2. 从程序集中获取所有hbm.xml文件,将它们添加到 Nhibernate 配置中
        private static ISessionFactory CreateSessionFactory() {
            var configuration = new Configuration();

            //here we add all hbm.xml mapping into configuration
            NHibernateHelpers.AddMapping(configuration);
            return configuration.BuildSessionFactory();
        }

//the trick is here, here we load all mappings
internal class NHibernateHelpers
    {        
        public static void AddMapping(Configuration cfg)
        {
            // you can use some params to replace it in the mapping file
            // for example if you need same tables with different data in it
            // Employee01, Enoloyee02 and in mapping file you could write something like  Employee<code>
            var @params = new Dictionary<string, object>
            {
               { "code", "01" },                
            };
            var assemblies = new Queue<Assembly>(AppDomain.CurrentDomain.GetAssemblies());
            var assemblyNames = assemblies.Select(ass => ass.FullName).ToList();

            while (assemblies.Count > 0)
            {
                Assembly ass = assemblies.Dequeue();
                //for each assebmly look for
                //ReferencedAssemblies and load them
                foreach (var refAss in ass.GetReferencedAssemblies())
                {
                    if (!assemblyNames.Contains(refAss.FullName))
                    {
                        // condition to load only your assemblies here we check for 
                        //unsigned one
                        if (refAss.GetPublicKeyToken().Length == 0)
                        {
                            assemblies.Enqueue(Assembly.Load(refAss.FullName));
                            assemblyNames.Add(refAss.FullName);
                        }
                    }
                }
            }

            List<Assembly> assembles = AppDomain.CurrentDomain.GetAssemblies().ToList();

            foreach (var assembly in assembles)
            {
                // if assembly is dynamic there is an Exception
                try
                {
                    var tmp = assembly.Location;
                }
                catch
                {
                    continue;
                }

                foreach (var resName in assembly.GetManifestResourceNames())
                {
                    if (resName.EndsWith(".hbm.xml"))
                    {
                        var str = new StreamReader(assembly.GetManifestResourceStream(resName)).ReadToEnd();
                        //here u can replace parameters you need I've left comment above
                        //str = str.Replace(...)
                        cfg.AddXmlString(str);
                    }
                }
            }
        }
    }
}

希望它会有所帮助。


推荐阅读