Как создать статический UnitOfWork для Entity Framework 4? - PullRequest
1 голос
/ 01 августа 2010

Учитывая этот класс

public class XQueries
{
    public IQueryable Query1()
    {
        using (XEntities context = new XEntities())
        {
            return something;
        }
    }

    public IQueryable Query2()
    {
        using (XEntities context = new XEntities())
        {
            return somethingElse;
        }
    }
}

Создано ли соединение с базой данных для каждого (XEntities context = new XEntities ()) {...}?Если да, то как правильно создать статический класс UnitOfWork, чтобы существовало только 1 соединение?

Ответы [ 2 ]

1 голос
/ 01 августа 2010

Нельзя создать статическую единицу работы, потому что по определению единица работы - это недолговечный объект. Поскольку EF ObjectContext спроектирован на основе шаблона единицы работы, плохая идея иметь один экземпляр ObjectContext в течение срока службы приложения. На это есть несколько причин.

Прежде всего, класс ObjectContext не является поточно-ориентированным. Это означает, что во время единицы работы одного пользователя (например, в веб-приложении) другой пользователь может зафиксировать свою единицу работы. Когда они совместно используют один и тот же ObjectContext, это означает, что в этой ситуации сохраняется только половина изменений, а изменения не являются транзакционными. Когда вам везет, ObjectContext терпит неудачу и выдает исключение. Когда вам не везет, вы повреждаете ObjectContext и в безопасности, загружаете дерьмо из вашей базы данных и в нее и узнаете, когда ваше приложение работает в рабочем состоянии (конечно, во время тестирования и постановки все всегда работает).

Во-вторых, ObjectContext имеет механизм кэширования, который предназначен для его кратковременного использования. Когда сущность извлекается из базы данных, она остается в кэше ObjectContext до тех пор, пока этот экземпляр не будет собран мусором. Когда вы сохраняете этот экземпляр в течение длительного периода времени, сущности устаревают. Особенно, если этот конкретный экземпляр ObjectContext не единственный, пишущий в эту базу данных.

0 голосов
/ 01 августа 2010

Entity Framework открывает соединения только при необходимости, например, для выполнения запроса или вызова SaveChanges, а затем закрывает соединение, когда операция завершена.

Из книги Мартина Фаулера «Образцы архитектуры корпоративных приложений» вуважение к единице работы.

Когда вы извлекаете данные из базы данных и из нее, важно отслеживать, что вы изменили;в противном случае эти данные не будут записаны обратно в базу данных.Точно так же вы должны вставить новые создаваемые вами объекты и удалить любые удаленные объекты.

Вы можете изменять базу данных при каждом изменении вашей объектной модели, но это может привести к множеству очень маленьких обращений к базе данных, что заканчиваетсябыть очень медленнымКроме того, требуется, чтобы у вас была открытая транзакция для всего взаимодействия, что нецелесообразно, если у вас есть бизнес-транзакция, охватывающая несколько запросов.Ситуация еще хуже, если вам нужно отслеживать объекты, которые вы прочитали, чтобы избежать непоследовательного чтения.

Единица работы отслеживает все, что вы делаете во время бизнес-транзакции, которая может повлиять на базу данных,Когда вы закончите, он выяснит все, что нужно сделать, чтобы изменить базу данных в результате вашей работы.

Всякий раз, когда я использую Entity Framework для клиентов (что я бы признал, эторедко) объект ObjectContext является реализацией Unit Of Work для системы.То есть ObjectContext будет в некоторой степени соответствовать трем утверждениям выше.Вместо того, чтобы слишком концентрироваться на абсолютно правильном определении с использованием ObjectContext, вам будет немного легче.

Проведите некоторое исследование шаблонов DI / IoC и Repository, что даст вам больше гибкости в решении вашей проблемы.

...