实体框架+存储库+单元或工作问题

pdi*_*ddy 5 .net entity-framework unit-of-work repository-pattern

我正在考虑使用EF 4开始一个新项目并阅读一些文章,我发现了一篇关于EF与存储库模式和工作单元的文章(http://blogs.msdn.com/b/adonet/archive/2009/ 06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx)

查看该文章,它使用ObjectContext作为UnitOfWork,并将其传递给Repository.

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

例如,我有一个管理操作日志的上下文和管理订单的另一个上下文.让我们说在我的业务层,我有一个名为AddOrder()的方法.AddOrder()将使用订单上下文创建新订单,但它也将使用操作日志上下文来创建新的操作日志条目.由于那些是2个上下文,我将不得不在两个上下文中调用save来提交....也许唯一的选择是只有一个上下文....

编辑:我的意思是2个不同类型的上下文,例如:OperationalLogContext和OrderContext.

Pur*_*ome 12

是的 - 我相信这是可能的.

踢球者是如何处理您的存储库.

例如,每个Repository都应该使用Context ..所以只需创建一个上下文并将其传递给每个存储库.

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

public interface IOrderRepository
{
    IQueryable<Order> FindAll();
}

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

public interface IUnitOfWork
{
    void Commit();
}
Run Code Online (Sandbox Code Playgroud)

.

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..
}
Run Code Online (Sandbox Code Playgroud)

.

public class OrderRepostiory : IOrderRepository
{
    private readonly SqlServerContext _sqlServerContext;
    public void OrderRepostiory(SqlServerContext sqlServerContext)
    {
        _sqlServerContext = sqlServerContext;
    }

    public IQueryable<Order> FindAll()
    {
        _sqlServerContext.Orders;
    }
}
Run Code Online (Sandbox Code Playgroud)

..最后,实例化.因为你的好男孩/女孩/彩虹独角兽,你会使用依赖注射..

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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

并且因为SqlServerContext被定义为HttpOrThreadLocal,它将立即进行ONCE并在多个存储库中重用.

不了解或了解DI/IoC?

那么这也有用......

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);
}
Run Code Online (Sandbox Code Playgroud)

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

HTH.