структура сущности + хранилище + единица или рабочий вопрос - PullRequest
5 голосов
/ 15 сентября 2010

Я думаю о запуске нового проекта с использованием 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 и передает его в репозиторий.

У меня вопрос: что если у меня есть 2 ObjectContext, что означает, что у меня будет 2 единицы работы, но я действительно хочу, чтобы все операции, выполняемые в этих двух контекстах, были одной единицей работы, возможен ли этот сценарий? Я не хочу вызывать сохранение для каждого контекста, я хотел бы, чтобы он был транзакционным .... без использования Transactionscope ...

Например, у меня есть контекст, который управляет журналом операций, и другой контекст, который управляет заказами. Скажем, на моем бизнес-уровне у меня есть метод AddOrder (). AddOrder () будет использовать контекст заказа для создания нового заказа, но он также будет использовать контекст журнала операций для создания новой записи журнала операций. Так как это 2 контекста, мне придется вызвать save в обоих контекстах для фиксации .... возможно, единственный вариант - иметь только один единственный контекст ....

РЕДАКТИРОВАТЬ: я имел в виду 2 контекста разных типов, например: OperationalLogContext и OrderContext.

1 Ответ

12 голосов
/ 15 сентября 2010

Да - я считаю, что это возможно.

Кикер - это способ обработки ваших репозиториев.

Например, каждый репозиторий должен принимать контекст ... поэтому просто создайте один контекст и передайте егокаждый репозиторий.

(код, пожалуйста!) Рад, что спросил:)

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;
    }
}

..и, наконец, создание экземпляров.Потому что вы хороший мальчик / девочка / радужный единорог, вы будете использовать Dependency Injection ..

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>();
    }
}

и поскольку SqlServerContext определен как HttpOrThreadLocal, он будет создан ОДИН РАЗ и повторно использован в нескольких репозиториях.

Не знаете или не понимаете 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);
}

еще раз, это все не проверенокод, который я только что набрал, когда я собирался ответить на этот вопрос.

HTH.

...