NHibernate не сохраняется с сеансом. Сохранение и транзакция. Коммит - PullRequest
0 голосов
/ 04 октября 2019

Я пытаюсь настроить NHibernate на ядре .net, но все еще безуспешно.

Я могу прочитать данные, но когда я пытаюсь сохранить или удалить, они не работают.

Слишком много информации, например, о том, как я создал свои службы, репозиторий и отображение, поэтому я пропущу некоторые файлы в этом вопросе, но все доступно на моем репозитории git .

ИтакУ меня очень простая модель.

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.

1 Ответ

1 голос
/ 05 октября 2019

Это потому, что вы открываете новый сеанс на каждом доступе к сеансу :

protected ISession Session => SessionFactory.OpenSession();

Транзакция начинается в одном сеансе, добавляется / удаляется в другом сбрасывании в третьем. Очевидно, вам нужно выполнить все операции за один сеанс.

Также вам не нужно вызывать Flush по умолчанию - он должен вызываться автоматически при transaction.Commit. И если вам действительно нужно вызвать Flush - сделайте это перед фиксацией транзакции.

...