NHibernate 不会坚持 session.Save 和 transaction.Commit
NHibernate don't persists with session.Save and transaction.Commit
我正在尝试在 .net 核心上配置 NHibernate,但仍然没有成功。
我可以读取数据,但是当我尝试保存或删除时,它不起作用。
关于我如何创建我的服务、存储库和映射等信息太多,所以我将跳过这个问题中的一些文件,但一切都在 my git repo。
所以我有一个非常简单的模型。
public class Book
{
public virtual Guid Id { get; set; }
public virtual string Title { get; set; }
}
我还创建了一个扩展方法,用于在我的服务中添加 nhibernate
public static class NHibernateExtensions
{
public static IServiceCollection AddNHibernate(this IServiceCollection services, string connectionString)
{
var mapper = new ModelMapper();
mapper.AddMappings(typeof(NHibernateExtensions).Assembly.ExportedTypes);
HbmMapping domainMapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
var configuration = new Configuration()
.DataBaseIntegration(c =>
{
c.Dialect<MsSql2012Dialect>();
c.ConnectionString = connectionString;
c.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
c.SchemaAction = SchemaAutoAction.Validate;
c.LogFormattedSql = true;
c.LogSqlInConsole = true;
});
configuration.AddMapping(domainMapping);
var fluentSessionFactory = Fluently
.Configure(configuration)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Book>())
.BuildSessionFactory();
var sessionFactory = configuration.BuildSessionFactory();
services.AddSingleton(fluentSessionFactory);
services.AddScoped(factory => fluentSessionFactory.OpenSession());
services.AddScoped<ISessionManager, SessionManager>();
return services;
}
}
这是我的StartUp
public void ConfigureServices(IServiceCollection services)
{
var connStr = Configuration.GetConnectionString("DefaultConnection");
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddNHibernate(connStr);
services.AddTransient<IBookRepository, BookRepository>();
services.AddTransient<IBookService, BookService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
我还创建了一个 BaseRepository
来处理简单的存储库操作。
我遇到的问题是,在 BaseRepository
中,当我调用 Add
时,它不会保留在数据库中。
public void Delete(T entity){
using (var transaction = Session.BeginTransaction())
{
Session.Delete(entity);
transaction.Commit();
Session.Flush();
}
}
当我调用 Queryable.ToList()
时,我得到了预期的一切。
我在配置上做错了什么,它不会保留在数据库中?
观察:数据库是 SQL Server 2017,运行 在 docker 容器上。
那是因为您在每个 Session access:
上打开新会话
protected ISession Session => SessionFactory.OpenSession();
交易在一个会话中开始add/delete在第三个刷新中。显然你需要在一个会话中完成所有操作。
此外,默认情况下您不需要调用 Flush - 它应该会在 transaction.Commit
上自动调用。如果您真的需要调用 Flush - 请在事务提交之前执行。
我正在尝试在 .net 核心上配置 NHibernate,但仍然没有成功。
我可以读取数据,但是当我尝试保存或删除时,它不起作用。
关于我如何创建我的服务、存储库和映射等信息太多,所以我将跳过这个问题中的一些文件,但一切都在 my git repo。
所以我有一个非常简单的模型。
public class Book
{
public virtual Guid Id { get; set; }
public virtual string Title { get; set; }
}
我还创建了一个扩展方法,用于在我的服务中添加 nhibernate
public static class NHibernateExtensions
{
public static IServiceCollection AddNHibernate(this IServiceCollection services, string connectionString)
{
var mapper = new ModelMapper();
mapper.AddMappings(typeof(NHibernateExtensions).Assembly.ExportedTypes);
HbmMapping domainMapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
var configuration = new Configuration()
.DataBaseIntegration(c =>
{
c.Dialect<MsSql2012Dialect>();
c.ConnectionString = connectionString;
c.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
c.SchemaAction = SchemaAutoAction.Validate;
c.LogFormattedSql = true;
c.LogSqlInConsole = true;
});
configuration.AddMapping(domainMapping);
var fluentSessionFactory = Fluently
.Configure(configuration)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Book>())
.BuildSessionFactory();
var sessionFactory = configuration.BuildSessionFactory();
services.AddSingleton(fluentSessionFactory);
services.AddScoped(factory => fluentSessionFactory.OpenSession());
services.AddScoped<ISessionManager, SessionManager>();
return services;
}
}
这是我的StartUp
public void ConfigureServices(IServiceCollection services)
{
var connStr = Configuration.GetConnectionString("DefaultConnection");
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddNHibernate(connStr);
services.AddTransient<IBookRepository, BookRepository>();
services.AddTransient<IBookService, BookService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
我还创建了一个 BaseRepository
来处理简单的存储库操作。
我遇到的问题是,在 BaseRepository
中,当我调用 Add
时,它不会保留在数据库中。
public void Delete(T entity){
using (var transaction = Session.BeginTransaction())
{
Session.Delete(entity);
transaction.Commit();
Session.Flush();
}
}
当我调用 Queryable.ToList()
时,我得到了预期的一切。
我在配置上做错了什么,它不会保留在数据库中?
观察:数据库是 SQL Server 2017,运行 在 docker 容器上。
那是因为您在每个 Session access:
上打开新会话protected ISession Session => SessionFactory.OpenSession();
交易在一个会话中开始add/delete在第三个刷新中。显然你需要在一个会话中完成所有操作。
此外,默认情况下您不需要调用 Flush - 它应该会在 transaction.Commit
上自动调用。如果您真的需要调用 Flush - 请在事务提交之前执行。