请教:如何在.NET Core 2.0项目中配置NHibernate 5.1
Hey there! I’ve worked through setting up NHibernate 5.1 in a .NET Core 2.0 API project before, so I can walk you through the exact steps to get it running smoothly. Here’s a step-by-step guide:
1. Install Required NuGet Packages
First, you’ll need to add the necessary packages to your project. Open the Package Manager Console or use Visual Studio’s NuGet Package Manager to install these:
NHibernate(stick to 5.1.x versions to ensure compatibility with .NET Core 2.0)Microsoft.Extensions.Configuration.Json(to read configuration fromappsettings.json)Microsoft.Extensions.DependencyInjection(for integrating NHibernate with .NET Core’s dependency injection)
2. Configure NHibernate
You have two main options for configuring NHibernate: using a traditional hibernate.cfg.xml file or code-based fluent configuration. Let’s cover both:
Option A: Using hibernate.cfg.xml
- Add a new XML file named
hibernate.cfg.xmlto your project. Set its Copy to Output Directory property to "Copy if newer". - Populate it with your database configuration. Here’s an example for SQL Server:
<?xml version="1.0" encoding="utf-8" ?> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <!-- Database connection settings --> <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> <property name="connection.connection_string">Your_SQL_Server_Connection_String</property> <property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property> <!-- Debug and schema settings --> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hbm2ddl.auto">update</property> <!-- Adjust to create/validate/none based on your needs --> <!-- Map your entities (point to the assembly containing your entity mappings) --> <mapping assembly="Your_Project_Assembly_Name" /> </session-factory> </hibernate-configuration>
- Replace
Your_SQL_Server_Connection_Stringwith your actual database connection string. - Replace
Your_Project_Assembly_Namewith the name of your project’s assembly where entity classes and mappings live.
Option B: Fluent Configuration (Code-Based)
If you prefer code over XML, set up NHibernate programmatically. Here’s a sample:
using NHibernate; using NHibernate.Cfg; using NHibernate.Mapping.ByCode; public static ISessionFactory CreateSessionFactory(string connectionString) { var configuration = new Configuration(); // Database settings configuration.DataBaseIntegration(db => { db.Driver<NHibernate.Driver.SqlClientDriver>(); db.Dialect<NHibernate.Dialect.MsSql2012Dialect>(); db.ConnectionString = connectionString; db.LogSqlInConsole = true; db.LogFormattedSql = true; }); // Add entity mappings (using NHibernate's ByCode approach) var mapper = new ModelMapper(); mapper.AddMappings(typeof(YourEntityMapping).Assembly.GetTypes()); configuration.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities()); return configuration.BuildSessionFactory(); }
- Replace
YourEntityMappingwith one of your entity mapping classes.
Tip: Pull Connection String from appsettings.json
To keep your connection string secure and configurable, add it to appsettings.json:
{ "ConnectionStrings": { "DefaultConnection": "Your_SQL_Server_Connection_String" } }
Then retrieve it in your configuration code:
var configBuilder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); var config = configBuilder.Build(); var connectionString = config.GetConnectionString("DefaultConnection");
3. Set Up Dependency Injection in Startup.cs
Next, register NHibernate’s core components with .NET Core’s DI container. Open Startup.cs and update the ConfigureServices method:
using NHibernate; using Microsoft.Extensions.Configuration; public void ConfigureServices(IServiceCollection services) { // Add MVC services services.AddMvc(); // Build configuration to access appsettings.json var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); // Register ISessionFactory as a singleton (one instance for the app's lifetime) services.AddSingleton<ISessionFactory>(sp => { // Use XML config approach var nhConfig = new Configuration(); nhConfig.Configure(); // Loads hibernate.cfg.xml from output directory // Uncomment below if using fluent config instead // var connectionString = configuration.GetConnectionString("DefaultConnection"); // return CreateSessionFactory(connectionString); return nhConfig.BuildSessionFactory(); }); // Register ISession as scoped (one session per HTTP request) services.AddScoped<ISession>(sp => { var sessionFactory = sp.GetRequiredService<ISessionFactory>(); return sessionFactory.OpenSession(); }); }
4. Use NHibernate in Your Controllers
Now you can inject ISession into your API controllers to perform database operations. Here’s an example:
using Microsoft.AspNetCore.Mvc; using NHibernate; using NHibernate.Linq; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; [Route("api/[controller]")] public class ProductsController : Controller { private readonly ISession _session; public ProductsController(ISession session) { _session = session; } [HttpGet] public async Task<IEnumerable<Product>> GetAll() { return await _session.Query<Product>().ToListAsync(); } [HttpGet("{id}")] public async Task<IActionResult> GetById(int id) { var product = await _session.GetAsync<Product>(id); if (product == null) return NotFound(); return Ok(product); } [HttpPost] public async Task<IActionResult> Create([FromBody] Product product) { if (!ModelState.IsValid) return BadRequest(ModelState); using (var transaction = _session.BeginTransaction()) { await _session.SaveAsync(product); await transaction.CommitAsync(); } return CreatedAtAction(nameof(GetById), new { id = product.Id }, product); } }
- Ensure your
Productentity has valid mappings (either via XML or fluent code).
Common Troubleshooting Tips
- Mapping Errors: Double-check that all entity mappings are correctly configured and their files are set to "Copy to Output Directory".
- Connection Issues: Verify your connection string is valid and accessible (especially if pulling from
appsettings.json). - DI Scoping: Always register
ISessionFactoryas a singleton andISessionas scoped—this ensures one session per request, which is NHibernate’s best practice.
内容的提问来源于stack exchange,提问作者seshireddy nangu

