Образцы Desing с использованием EntityFramework?

Интерфейс

public Интерфейс IDinnerRepository 
{
    IQueryable FindAllDinners();
    IQueryable FindDinnersByText(string q);

    Dinner GetDinner(int id);

    void Add(Dinner dinner);
    void Delete(Dinner dinner);

    void Save();
}

Class that is inherited from above Интерфейс

public class DinnerRepository : NerdDinner.Models.IDinnerRepository
{
    NerdDinnerEntities db = new NerdDinnerEntities();

    Public IQueryable FindDinnersByText(string q)
    {
         return db.Dinners.Where(d => d.Title.Contains(q)
             || d.Description.Contains(q)
             || d.HostedBy.Contains(q));
    }

    public IQueryable FindAllDinners()
    {
         return db.Dinners;
    }

    public Dinner GetDinner(int id)
    {
        return db.Dinners.SingleOrDefault(d => d.DinnerID == id);
    }

    public void Add(Dinner dinner)
    {
        db.Dinners.AddObject(dinner);
    }

    public void Delete(Dinner dinner)
    {
        foreach (RSVP rsvp in dinner.RSVPs.ToList())
            db.RSVPs.DeleteObject(rsvp);

        db.Dinners.DeleteObject(dinner);
   }

   public void Save()
   {
        db.SaveChanges();
   }
}

Использование в программе

public class DinnerOperation
{
    DinnerRepository dr = new DinnerRepository();

   //insert
    public void InsertDinner()
    {
        Dinner dinner = dr.GetDinner(5);
        dr.Dinner.Add(dinner);
        dr.Save();
    }

   //delete
    public void DeleteDinner()
    {
        Dinner dinner = dr.GetDinner(5);
        dr.Dinner.Delete(dinner);
        dr.Save();
    }
}

И не используя шаблон разработки хранилища...

public class DinnerOperation
{
    DinnerEntities entity = new DinnerEntities();

   //insert
    public void InsertDinner()
    {
        Dinner dinner = entity.Dinners.Find(5);
        entity.Dinner.Add(dinner);
        entity.SaveChanges();
    }

   //delete
    public void DeleteDinner()
    {
        Dinner dinner = entity.Dinners.Find(5);
        entity.Dinner.Remove(dinner);
        entity.SaveChanges();
    }
}

Вопрос

Я не могу понять, в здесь, Почему мы использовали шаблон разработки? Когда использование шаблона разработки Хранилища со Структурой Предприятия таким образом ничего не означает.

Как я могу использовать шаблон разработки с entitiy структурой? Когда имеет смысл использовать шаблон разработки со структурой предприятия?

4
nl ja de

3 ответы

Вы почти получили его. Во-первых, повторно учтите свой операционный класс ужина так, чтобы внедрение хранилища могло быть введено в него.

public class DinnerOperation
{
  private IDinnerRepository dr;
  public DinnerOperation( IDinnerRespository repository ) {
     this.dr = repository;
  }

 //insert
  public void InsertDinner()
  {
      Dinner dinner = dr.GetDinner(5);
      dr.Dinner.Add(dinner);
      dr.Save();
  }

 //delete
  public void DeleteDinner()
  {
      Dinner dinner = dr.GetDinner(5);
      dr.Dinner.Delete(dinner);
      dr.Save();
  }
}

Тогда осуществите различные хранилища:

public class EntityFrameworkDinnerRepository : IDinnerRepository
public class NHibernateDinnerRepository : IDinnerRepository
public class Linq2SqlDinnerRepository : IDinnerRepository
public class MockDinnerRepository : IDinnerRepository
....

и затем используйте любое хранилище, которое вы хотите:

var repository = new ....Repository();
var operation = new DinnerOperation( repository );

operation.GetDinner(5);

Хранилища используются, чтобы резюмировать ваших конкретных провайдеров данных и таким образом создание вашей архитектуры больше felible.

Хотите переключиться на nHibernate?

Болезненный, если у вас есть EntityFramework везде. Легкий, если вы используете хранилища, вы просто вводите другое хранилище, и ваша бизнес-логика не должна изменяться.

Хотите к тесту единицы свою бизнес-логику?

Болезненный, если вы, придерживаются конкретного провайдера данных. Легкий, если у вас есть хранилища, вы просто вводите inmemory хранилище, которое даже не использует базу данных.

Получил его теперь?

6
добавлено
Большое Спасибо. Есть много вещи учиться:). Есть ли любые обучающие программы, статьи, и т.д.... об этой теме. Я почти получил его. Что вы рекомендуете получить лучшее понимание?
добавлено автор AliRıza Adıyahşi, источник
Переключение от EF до NH или поставщика в памяти или независимо от того, что не "легко" с хранилищем, которое выставляет IQueryable .
добавлено автор Slauma, источник
Да, NH поддерживает LINQ, но не тот же самый LINQ как EF (LINQ к предприятиям), и LINQ к предприятиям не LINQ к объектам, ни LINQ-to-SQL. У вас могут быть тот же самый код LINQ, все компилирование, но можно работать, другой doesn' t или это ведет себя по-другому. It' s иждивенец поставщика и вы не можете проверить с кодом, которые используют поставщика 1, если код, который использует поставщика 2, работает. It' s лучше объяснил здесь, что я имею в виду: stackoverflow.com/a/6904479/270591 (включая связи в конце ответа).
добавлено автор Slauma, источник
Я don' t помнят любой краткий все же полный источник. Просто Google на "Образце хранилища объяснил", читают еще немного обучающих программ и изучают образец Внедрения зависимости, который играет хорошо вместе с образцом Хранилища.
добавлено автор Wiktor Zychla, источник
@Slauma: это удивительно легко, так как библиотека классов содержит метод расширения AsQueryable на IEnumerables. msdn.microsoft.com/pl-pl/library/bb353734.aspx Также NH поддерживает linq. Мне осуществили мои хранилища для linq2sql, nhibernate, ef, xpo и в памяти и оба осуществляют те же самые интерфейсы.
добавлено автор Wiktor Zychla, источник
@Slauma: Я знаю об этих возможных проблемах. Обсуждение, где нужно осуществить хранилища, чтобы возвратить iqueryables, конечно, вне этого.
добавлено автор Wiktor Zychla, источник

Я отказываюсь использовать образец хранилища, когда я использую ORM. Я думаю, что у этого есть очень мало если любая выгода в этом случае. (Да, я ожидаю спускаться проголосовавший приблизительно 2,000 раз зилотами).

С EF я создаю интерфейс для своего Контекста

public interface IDinnerContext : IDisposable
{
    IDbSet Dinners;

    int SaveChanges();
}

Я тогда прикрепляю этот интерфейс на свои внедрения EF DatabaseContext и альт! Я могу использовать EF везде, тест единицы мой db доступ с ЛОЖНЫМИ внедрениями, использовать инъекцию, если я желаю, и не заканчиваю с 6 миллионами методов GetByXXX. Ручки IQeryable, что, и я получаю задержанное выполнение. Я не действительно должен Вставлять/Удалять методы, потому что IDBSet уже имеет, Добавляют/Удаляют. Я имею более чистый/легче, чтобы прочитать код с меньшим количеством абстракций.

Если у меня ДЕЙСТВИТЕЛЬНО есть случай, где тот же самый вопрос используется во многих различных местах, и я действительно хочу, чтобы это было распространено, то я могу добавить некоторый механизм, чтобы поддержать это. Однако 95% времени, вопросы характерны для компонента, ответственного за бизнес-логику X (что-либо вне простых заявлений GetBy). Таким образом, я не рассматриваю что как проблему.

Не понимайте меня превратно, я использовал образец хранилища неукоснительно, пока ORMs не стал довольно достойным. Как только ORMs достиг определенного уровня изощренности, я чувствовал, образец хранилища больше не может требоваться и начал делать проекты без него.... и никогда не оглядывался назад. Я думаю, что все остальные будут в конечном счете следовать в этом направлении или чем-то весьма схожем, но оно будет требовать времени для старых привычек умереть. (Я знаю некоторые devs, которые все еще настаивают на том, чтобы использовать замок (это) потому что все еще в некоторых образцах MS).

5
добавлено
+1. другая точка зрения. Я немного смущен После вашего ответа. Я думаю, опыт требуется, решая который использовать. Это дало мне моральный дух, чтобы продолжить кодировать. Спасибо Грита...
добавлено автор AliRıza Adıyahşi, источник
Хм, я предполагаю меня вид сделанных предположений там о том, что понимали/знали люди. Есть 2 главных причины, люди непреклонны по отношению к использованию образца хранилища. 1) поблочное тестирование, 2) подвергните сомнению повторное использование. Поблочное тестирование теперь очень легко сделать в EF с IDbContext. Повторное использование вопроса может быть обработано также, хотя я полагаю, что с компонентом, который ведут развитием есть очень мало наложения в фактическом использовании вопроса между компонентами, таким образом, только необходимо управлять им на составляющем уровне, который достаточно легко сделать..., но я все еще предпочитаю усиливать гибкость EF/IQueryable вместо этого.
добавлено автор Keith, источник

Это - образец Хранилища , который сам по себе был бы лишним со Структурой Предприятия, потому что DbContext служит Хранилищем и Единицей работы в то же время, но это не mockable - нет никакого IDbContext . Таким образом, вы заканчиваете тем, что поместили DbContext в тонкой обертке хранилища, таким образом, можно легко проверить компоненты позже.

Я думаю, что стоит упомянуть, что я никогда не использовал образец Хранилища с NHibernate, потому что фабрика сессии и сессии - интерфейсы - ISession и ISessionFactory соответственно.

При использовании хранилище интерфейсом где-нибудь ( IRepository ) и вводите его, тестирование дразнить/гасить, будет намного легче:

public class DinnerOperation
{
    private readonly IDinnerRepository repository;

    public DinnerOperation(IDinnerRepository dinnerRepository)
    {
        repository = dinnerRepository;
    }
}

Конечно, вы должны были бы использовать контейнер МОК выбора ввести правильный случай для вас ( DinnerRepository в этом случае) или делаете DI 'вручную'.

Тем путем можно проверить DinnerOperation класс против дразнившего или погашенного хранилища. Когда вы иллюстрируете примерами DbContext , вы не можете.

2
добавлено
Большое спасибо...
добавлено автор AliRıza Adıyahşi, источник
Верный @Keith, было крайне трудно сделать прежде. Я, должно быть, пропустил интерфейс IDbContext , но спасибо за наконечник, я исследую тему немного далее.:)
добавлено автор Patryk Ćwiek, источник
@Keith I can' t считают любое понятие IDbContext интерфейс, являющийся легко доступным в EF 5.0 +. (Есть IDbSet , хотя) Все, что я могу найти, является таможенными используемыми решениями; если у вас есть что-нибудь, чтобы указать мне к упомянутому интерфейсу, I' d ценят его. Конечно, если it' s катившее обычаем решение, тогда я могу сделать то же самое самостоятельно;)
добавлено автор Patryk Ćwiek, источник
Структура предприятия mockable.... теперь. Вы, вероятно, думаете о предыдущих версиях, которые сделали его невероятно болезненным, чтобы сделать так. Теперь, как вы видите на моем посту выше, можно использовать Интерфейс (IDbContext) для контекста вместо DbContext, таким образом позволяя вам легко проверить компоненты.
добавлено автор Keith, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot