Выставление транзакций в репозитории.NHibernate - PullRequest
1 голос
/ 24 февраля 2012

Итак, на данный момент у меня есть такая реализация репозитория:

public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
    private ISession session;

    public Repository(ISession session)
    {
        this.session = session;
    }

    public T Get(Guid id)
    {            
        return this.session.Get<T>(id);            
    }
    public IQueryable<T> Get(Expression<Func<T, Boolean>> predicate)
    {
        return this.session.Query<T>().Where(predicate);            
    }
    public IQueryable<T> Get()
    {
        return this.session.Query<T>();            
    }
    public T Load(Guid id)
    {
        return this.session.Load<T>(id);
    }
    public void Add(T entity)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Save(entity);
            transaction.Commit();
        }
    }
    public void Remove(T entity)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Delete(entity);
            transaction.Commit();
        }
    }
    public void Remove(Guid id)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Delete(this.session.Load<T>(id));
            transaction.Commit();
        }
    }
    public void Update(T entity)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Update(entity);
            transaction.Commit();
        }
    }
    public void Update(Guid id)
    {            
        using(var transaction = this.session.BeginTransaction())
        {
            this.session.Update(this.session.Load<T>(id));
            transaction.Commit();
        }
    }
}

Тогда я использую Ninject модуль, как это.

public class DataAccessModule : Ninject.Modules.NinjectModule
{
    public override void Load()
    {
        this.Bind<ISessionFactory>()
            .ToMethod(c => new Configuration().Configure().BuildSessionFactory())
            .InSingletonScope();

        this.Bind<ISession>()
            .ToMethod(ctx => ctx.Kernel.TryGet<ISessionFactory>().OpenSession())
            .InRequestScope();

        this.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
    }
}

Экспорт и обновление схемы называются тестами:

[TestFixture]
public class SchemaManipulations
{
    [Test]
    [Ignore]
    public void CreateDatabaseSchema()
    {
        new SchemaExport(new Configuration().Configure()).Create(false, true);
    }

    [Test]
    [Ignore]
    public void UpdateDatabaseSchema()
    {
        new SchemaUpdate(new Configuration().Configure()).Execute(false, true);
    }
}

Я сохраняю «чистоту» моего уровня домена: логика проверки реализована с помощью FluentValidation, она не знает ни NHibernate, ни чего-либо еще.

И это казалось мне идеальным ... пока я не задумался, как реализовать параллелизм версий. Я решил использовать optimistic-locking, и для правильного сопоставления для NH это не было проблемой. И мне нужно было знать, как обрабатывать транзакции, как сообщить пользователю при редактировании элемента locked?

Итак, появился еще один вопрос Управление параллелизмом версии для длинной сессии. NHibernate. ASP.NET MVC , где было сказано, что показ транзакции на Repository не рекомендуется.

ВОПРОС САМ

Я уже слышал о SharpArchitecture и о UOW. И этого вполне достаточно .

Но меня интересуют проблемы, связанные с моим решением стратегии доступа к данным: с какими ошибками / сбоями я столкнусь при таком использовании?

Также будет ли решением использовать предложенный Kaleb Pederson NHibernate, транзакции и TransactionScope подход?

Спасибо!

1 Ответ

1 голос
/ 24 февраля 2012

как бы вы написали код, подобный этому?

// Save both together or none of it
rep1.Save(newSomeEntity);
rep2.Save(SomeOtherEntity);

без него внутри репозитория легко

var rep1 = new Repository<SomeEntity>(session);
var rep2 = new Repository<SomeOtherEntity>(session);
using (var tx = session.BeginTransaction())
{
    try
    {
        rep1.Save(newSomeEntity);
        rep2.Save(SomeOtherEntity);
        tx.Commit();
    }
    catch (SomeException ex)
    {
        Handle(ex);
        tx.RollBack();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...