repository-pattern – 应用程序架构 – 与RavenDB交易

我正在一个项目中实现RavenDB,经过几天尝试数据库,我现在正在构建这个应用程序,但我有一个问题.

我正在为每个实体编写业务层(几乎),并且我有一个处理查询和DocumentStore的唯一存储库类.
我对如何沿服务层共享DocumentStore并处理事务感到困惑.

我正在展示一个例子,我试图在单个事务中存储和读取文档.

存储库的一个示例:

public class RavenRepository
{
    private static DocumentStore _store;
    private IDocumentSession _session;

    public RavenRepository(DocumentStore store)
    {
        _store = (_store==null) ? new DocumentStore() { Url = "http://wsk-gcardoso:8081" } : store;           
    }
    public T SingleOrDefault<T>(Func<T, bool> predicate) where T : BaseModel
    {
        using (var session = _store.OpenSession())
        {
            return session.Query<T>().SingleOrDefault(predicate);
        }
    }
    public T Add<T>(T item) where T : BaseModel
    {            
        using (var session = _store.OpenSession())
        {
            session.Advanced.AllowNonAuthoritiveInformation = this.AllowNonAuthoritiveInformation;
            session.Store(item);
            session.SaveChanges();
        }
        return item;
    }
    public void Initialize() {
        _store.Initialize();
    }
    public void Dispose() {
        _store.Dispose();
    }
}

业务层将是这样的:

public class NewsletterBusiness
{
    private RavenRepository repository;
    public NewsletterBusiness(RavenRepository ravenRepository)
    {       
        repository = (ravenRepository == null) ? RavenRepository(null) : ravenRepository;
    }

    public Newsletter Add(Newsletter newsletter)
    {
        Newsletter news = repository.Add(newsletter);
        return news;
    }
    public Newsletter GetById(long Id)
    {
        Newsletter news = repository.SingleOrDefault<Newsletter>(x => x.Id == Id);
        return news;
    }
}

现在我正在尝试保存并在同一事务中读取一个对象(新闻简报).
根据我的阅读,我必须将documentStore的AllowNonAuthoritativeInformation设置为false,等待事务完成.但是从我处理图层和存储库的方式来看,我是在单个事务中存储和查询数据库吗?

说实话,我觉得我对商店的OpenSession方法感到困惑.我想我把会话和交易搞混了.

例如,这段代码:

var repository = new RavenRepository(null);
newsletterBusiness = new NewsletterBusiness(repository);
repository.Initialize();
using (var tx = new TransactionScope())
{
    Newsletter new = newsletterBusiness.Add(new Newsletter { Title = "Created by Tests", Content = "Created By Tests" });

    Newsletter objectCreated = newsletterBusiness.GetById(new.Id);
    repository.Dispose();
    tx.Complete();
}

如果我创建第二个业务层(例如图片)并且我设置了picturesBusiness.repository = repository(同样的“为businessLayer设置的RavenRepository对象)”,我将在newsletterBusiness.repository的同一个会话中工作?

picturesBusiness = new PicturesBusiness(repository);
Picture pic = picturesBusiness.GetById(20);

我真的很感谢这方面的帮助,
来自葡萄牙的干杯!

您没有正确使用RavenDB,这就是您遇到此问题的原因.
您可以将会话视为数据库连接.在您的模型中,您将为每种类型创建单独的会话.但是你真的没有理由想要这样做.

实际上,您不希望这样做,因为会话完全能够同时处理多个类型.
此外,您所做的实际上是减少会话机会来优化诸如将更新一次发送到服务器之类的事情.

如果您希望进行跨越类型的事务性写入,则根据您的体系结构,您必须使用DTC,因为每个不同的会话都是与数据库的不同连接.如果您使用Session per Request模型,那么您将只有一个会话,并且只需调用一次SaveChanges()就可以获得事务语义.

相关文章
相关标签/搜索