.net 实体框架&x2B;存储库&x2B;单位或工作问题

.net 实体框架&x2B;存储库&x2B;单位或工作问题,.net,entity-framework,repository-pattern,unit-of-work,.net,Entity Framework,Repository Pattern,Unit Of Work,我正在考虑使用EF4启动一个新项目,并阅读了一些文章,我发现了一篇关于EF的文章,其中包含存储库模式和工作单元() 看看那篇文章,它使用ObjectContext作为工作单元,并将其传递给存储库 我的问题是,如果我有2个ObjectContext,这意味着我将有2个工作单元,但我实际上希望在这2个上下文上执行的所有操作都是一个工作单元,这种情况可能吗?我不想在每个上下文上调用save,我希望它是事务性的。。。。不使用transactionscope 例如,我有一个管理操作日志的上下文和另一个管理

我正在考虑使用EF4启动一个新项目,并阅读了一些文章,我发现了一篇关于EF的文章,其中包含存储库模式和工作单元()

看看那篇文章,它使用ObjectContext作为工作单元,并将其传递给存储库

我的问题是,如果我有2个ObjectContext,这意味着我将有2个工作单元,但我实际上希望在这2个上下文上执行的所有操作都是一个工作单元,这种情况可能吗?我不想在每个上下文上调用save,我希望它是事务性的。。。。不使用transactionscope

例如,我有一个管理操作日志的上下文和另一个管理订单的上下文。假设在我的业务层中,有一个名为AddOrder()的方法。AddOrder()将使用订单上下文创建新订单,但它也将使用操作日志上下文创建新的操作日志条目。因为这是两个上下文,所以我必须在两个上下文上调用save来提交。。。。也许唯一的选择是只有一个上下文


编辑:我指的是两种不同类型的上下文,例如:OperationalLogContext和OrderContext。

是的-我相信这是可能的

关键在于如何处理存储库

例如,每个存储库都应该有一个上下文。。因此,只需创建一个上下文并将其传递给每个存储库

(请输入代码!)很高兴你问:)

再一次,这些都是我刚刚输入的未经测试的代码,因为我正在考虑回答这个问题


嗯。

谢谢,这很有帮助。所以唯一的方法就是只有一个上下文。。。如果我有两个上下文,那么我将别无选择,只能求助于某种事务机制,对吗?不。你想要多少就有多少。注意,对于依赖项注入,我是如何说HttpScopeOrThreadScope的?您可以将其更改为singleton(坏主意)或默认值,即每次请求对象时都创建一个新实例。所以这取决于你:)如果你用第二种方法(我用了一个测试例子),那么是的。。你必须一个接一个地手动更新每个上下文。eg
var context1=新SSC(…);var上下文2=新SSC(…)_或=新的或(上下文1)_olr=新的olr(上下文2)等等。我必须更新我的答案-我有一个严重的错误。如果上下文没有创建
EntityConnection(connectionString)
,我就用普通的
connectionString
替换了对
新EntityConnection(connectionString)
的任何引用,因为没有处理连接(而不是将一个连接传递给它)。为Ayende Rahien(来自休眠Rhino)的修复方案干杯。我指的是2种不同类型的上下文,例如:OperationalLogContext和OrderContext。我认为您指的是同一类型的多个上下文(SqlServerContext),operationalLog模型和ordermodel位于SqlServerContext中。我的意思是OperationalLogContext将管理操作模型,ordercontext管理订单模型。抱歉搞混了。啊,是的我误解了你的问题:(我以为你想避免使用2个上下文,因为你有2个存储库。出于兴趣,为什么你想要2个上下文?其次-这里有一个相关的问题,刚才有人问:
public interface IOrderRepository
{
    IQueryable<Order> FindAll();
}

public interface IOperationLogRepository
{
    IQueryable<OperationLog> FindAll();
}

public interface IUnitOfWork
{
    void Commit();
}
public class SqlServerContext : ObjectContext, IUnitOfWork
{
    public void SqlServerContext(string connectionString) 
        : base(connectionString)
    {
    }

    public void Commit()
    {
        this.SaveChanges();
    }

    // Your other POCO's and stuff here ..etc..
}
public class OrderRepostiory : IOrderRepository
{
    private readonly SqlServerContext _sqlServerContext;
    public void OrderRepostiory(SqlServerContext sqlServerContext)
    {
        _sqlServerContext = sqlServerContext;
    }

    public IQueryable<Order> FindAll()
    {
        _sqlServerContext.Orders;
    }
}
public class SqlServerRegistry : Registry
{
    public SqlServerRegistry(string connectionString)
    {
        For<SqlServerContext>()
            .HybridHttpOrThreadLocalScoped()
            .Use<SqlServerContext>()
            .Ctor<string>("connectionString")
                .Is(connectionString);

        For<IOrderRepository>().Use<OrderRepository>();
        For<IOperationLogRepository>().Use<OperationLogRepository>();
    }
}
private SqlServerContext _sqlServerContext;
private IOrderRepository _orderRepository;
private IOperationLogRepository _operationLogRepository;

[TestInitialize]
public void TestInitialise()
{
    _sqlServerContext = new SqlServerContext(
             ConfigurationManager.AppSettings["connectionString"]);
    _orderRepository = new OrderRepository(_sqlServerContext);
    _operationLogRepository= new OperationLogRepository(_sqlServerContext);
}

[TestMethod]
public void SomeTest()
{
    // Arrange.
    const int count = 10;

    // Act.
    var orders = _orderRepository.FindAll().Take(10).ToArray();

    // Assert.
    Assert.IsNotNull(orders);
    CollectionAssert.AllItemsAreNotNull(orders);
    Assert.AreEqual(count, orders.Length);
}