Вопрос по .net, entity-framework, c#, design-patterns – Что такое единица работы в EF?

35

Я изучаю EF и видел много примеров, и во время обучения я узнал об использовании репозитория и единиц работы. Я получил, почему использовать репозиторий, но у меня нет понимания единицы работы на самом деле.

Отсутствие понимания затрудняет понимание DAL. Пожалуйста, ведите меня.

Спасибо

Ваш Ответ

3   ответа
33

Таким образом, ваш DAL будет сохранять, удалять и извлекать объекты, а ваш DataContext / ObjectContext будет отслеживать ваши объекты, управлять транзакциями и применять изменения.

Это примерjust to illustrate the idea of the solution.

using(var context = new ObjectContext()) { // Unit of Work
    var repo = new ProductRepository(context);
    var product = repo.GetXXXXXXX(...);
    ...

    // Do whatever tracking you want to do with the object context. For instance:
    // if( error == false) { 
    //     context.DetectChanges();
    //     context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
    // }
}

И ваш репозиторий будет выглядеть так:

public abstract class Repository {

    public Respository(ObjectContext context){
        CurrentContext = context;
    }

    protected ObjectContext CurrentContext { get; private set; } 
}

public class ProductRespository : Repository {
    public ProductRespository(ObjectContext context) : base(context){
    }

    public Product GetXXXXXX(...){
        return CurrentContext... ; //Do something with the context
    }
}    

Другой способ - это глобальная единица работы (контекст объекта):

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

public static class ContextProvider {

    public static ObjectContext CurrentContext {
        get { return HttpContext.Items["CurrentObjectContext"];
    }

    public static void OpenNew(){
        var context = new ObjectContext();
        HttpContext.Items["CurrentObjectContext"] = context; 
    }

    public static void CloseCurrent(){
        var context = CurrentContext;
        HttpContext.Items["CurrentObjectContext"] = null;
        // Do whatever tracking you want to do with the object context. For instance:
        // if( error == false) { 
        //     context.DetectChanges();
        //     context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
        // }
        context.Dispose();
    }
}

В этом примере ObjectContext является единицей работы, и он будет жить в текущем запросе. В ваш глобальный asax вы можете добавить:

protected void Application_BeginRequest(object sender, EventArgs e){
    ContextProvider.OpenNew();
}

protected void Application_EndRequest(object sender, EventArgs e){
    ContextProvider.CloseCurrent();
}

В ваших репозиториях вы просто звонитеContextProvider.CurrentContext

Он всегда будет вызываться при завершении запроса. NHibernate реализует это управление сессиями, используя его и всегда работал как шарм. Шаблон называется открытым сеансом в поле зрения.
Я реализую свою единицу работы точно так же, за исключением того, что вместоOpenNewЯ лениво загружаю мои контексты. Тем не менее, я все еще чувствую себя неловко, когда я используюApplication_EndRequest Распорядиться контекстами. Знаете ли вы, насколько гарантировано, что это событие произойдет и завершится?
ivowiblo не могли бы вы привести пример кода? или ссылка? Спасибо haansi
Добавил пример
Добавлен еще один пример :)
13
Unit of Work

Maintains a list of objects affected by a business transaction and coordinates the writing
out of changes and the resolution of concurrency problems.

enter image description here

When you're pulling data in and out of a database, it's important to keep track of what you've changed; otherwise, that data won't be written back into the database. Similarly you have to insert new objects you create and remove any objects you delete.

You can change the database with each change to your object model, but this can lead to lots of very small database calls, which ends up being very slow. Furthermore it requires you to have a transaction open for the whole interaction, which is impractical if you have a business transaction that spans multiple requests. The situation is even worse if you need to keep track of the objects you've read so you can avoid inconsistent reads.

A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.

http://martinfowler.com/eaaCatalog/unitOfWork.html

@MartinBean: часть вопроса былаI do not have understanding of unit of work really is., Поскольку М.Фаулер писал об этом довольно хорошо, цитируемый отрывок является тематическим. Ссылка не будет достаточной, поскольку ответы только на ссылки весьма ненавистны из-за их способности ломаться. Следовательно, предоставление ссылки и копирование описания кажется минималистичным действительным частичным ответом. Минималистичный, частичный, но все же ответ. Это конечно мое личное мнение.
а как насчет эф?
На самом деле это не ответ. Вы только что скопировали и вставили описание из ресурса.
22

е корпоративного программного обеспечения являетсяUnit of Work, По словам Мартина Фаулера,Единица работы & quot; поддерживает список объектов, затронутых бизнес-транзакцией, и координирует выписывание изменений и решение проблем параллелизма. & quot;

The Unit of Work pattern isn't necessarily something that you will explicitly build yourself, но шаблон обнаруживается почти в каждом инструменте персистентности, о котором я знаю. Интерфейс ITransaction в NHibernate, класс DataContext в LINQ to SQL и класс ObjectContext в Entity Framework - все это примеры единицы работы. В этом отношении,the venerable DataSet can be used as a Unit of Work.

Для более подробной информации, пожалуйста, нажмитеВот чтобы прочитать эту статью, она хорошая.

Чтобы ознакомиться с руководством по внедрению шаблонов репозитория и единиц работы в приложении ASP.NET MVC (MVC 4 и EF 5) (9 из 10), щелкнитеВот

Для EF 6 и MVC 5, пожалуйста, нажмитеВот

Я надеюсь, что это поможет, это помогло мне!

enter image description here

Похожие вопросы