Интерфейс (интерфейс в интерфейсе) в Entity Framework - PullRequest
2 голосов
/ 12 марта 2012

У меня есть две сущности в структуре сущностей. Теперь я хочу отделить их, поместив интерфейс объекта DAL в домен.

Таким образом, конечный результат будет:

DAL

  • Персона: IPerson (EF Entity)
  • Книга: IBook (EF Entity)

Домен

  • Интерфейсы (папка)
    • IPerson
    • IBook
  • Персона (Доменная сущность)
  • Книга (Доменная сущность)

Теперь проблема в том, должен ли мой Dal.Person иметь виртуальную Книгу или IBook? Как должны выглядеть DAL.Person, IPerson и Domain.Person (приведите просто небольшой пример взаимодействия)

Ответы [ 4 ]

1 голос
/ 12 марта 2012

Ответ на ваш вопрос полностью зависит от вашей цели здесь.

Если вы создаете интерфейсы уровня домена с обоснованием, которое вы можете (на каком-то этапе позже) переключить через DAL из Entity Framework на что-то совершенно иное (например, сторонний веб-сервис или, возможно, сериализацию xml)) - тогда вы будете стремиться полностью отделить любую конкретную логику между Доменом и DAL.

Где это возможно, вы хотите, чтобы ваш Домен работал на объектах / интерфейсах Домена и вашем DALработать с объектами / интерфейсами DAL, в то же время реализуя интерфейсы, указанные в вашем Доступе к данным

Следовательно, ваш объект DAL DAL.Person должен содержать объект Book и реализовываться из интерфейса IPerson на уровне домена.

Я приведу несколько примеров в соответствии с просьбой:

#region Domain Objects


    public interface IPerson
    {
        List<IBook> Books { get; private set; }
    }

    public interface IBook
    {
        string Name { get; private set; }
    }

    #endregion

    #region DAL/Entity Framework Auto Generated classes

    public class Person : IPerson
    {
        public List<Book> Books {get; private set;}
    }

    public class Book : IBook
    {
        public string Name { get; private set; }
    }

  #endregion

Вопреки комментарию Джодрелла, я думаю, что если бы было требование «горячей замены» уровня доступа к данным, это может быть случайдля уровня DataAccess, реализующего контракты интерфейса, описанные на уровне домена.

Честно говоря, я редко встречал это требование - и обычно лучше всего расширять автоматически сгенерированные классы Entity Framework (до partial) и обходить приложение, удаляядублирование, которое потребуется при указании объектов домена и самих контрактов.Таким образом, по сути, ваши классы Entity-Framework становятся вашим уровнем домена.

И я должен упомянуть, что вы должны использовать классы POCO согласно комментариям выше

1 голос
/ 07 марта 2013

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

Я бы предложил реализовать слой Repository..

Шаг 1

Начните с самого простого шаблона - модели (Персона и Книга) в домене и EF на уровне DAL, используя стандартную процедуру EF для кодапервый.EF реализует функции репозитория в DbSet<Person> и DbSet<Book> (но, конечно, этот тип репозитория заблокирован в EF).

Чтобы приложение с возможностью работы работало с этим шаблоном, вы можете довольно быстро продемонстрировать функциональность.Это позволяет вам сосредоточиться на логике приложения и не беспокоиться о постоянстве.

Шаг 2

Поместить класс или классы хранилища между доменом и DAL.Замените доменные вызовы на DbSet<Person> и DbSet<Book> на звонки на IQueryable<Person> и IQueryable<Book> в хранилище.Коллекции репозитория изначально просто указывают на коллекции EF DbSet<>.

Реализуйте Save () также в репозитории.Первоначально он просто вызывает DbContext.SaveChanges ().

Проверьте, что функциональность остается прежней.

Шаг 3

Замените источник хранилищаIQueryable<> с тем, что эквивалентно в вашем новом DAL.Это может быть или не быть хитрым, в зависимости от формы нового DAL.

Я следовал этому типу процесса - начал с сериализированного XML DAL, переместил его в EF, реорганизовал одну таблицу обратно в локальный XMLфайл, и следующим шагом будет рефакторинг другой таблицы в веб-службу на ESB.

BTW , вы упомянули замену EF на SQL для повышения производительности.Мы обнаружили, что EF медленный для массовых вставок, потому что он использует стиль строка за строкой.

Чтобы обойти это, я реализовал SqlBulkCopy в репозитории на основе EF (вместо оптовой замены EF, которая имеет другие функциинам очень понравилось).Это быстро, но требует времени, чтобы собрать воедино.

1 голос
/ 12 марта 2012

EF не поддерживает работу с интерфейсами, поэтому у вас не может быть public virtual IBook ... в вашей сущности Person, если вы хотите использовать ее как свойство навигации, обрабатываемое EF.

0 голосов
/ 11 ноября 2014

У меня была эта проблема для AGES.

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

По сути, вы выставляете ДВА ссылки в вашем - в вашем конкретном классе - один реализует книгу Ibook, а другой - книгу BookNavigation

, первый реализуетИнтерфейс требований (Ibook) и второй реализует конкретный класс, чтобы сделать EF Happy.Затем вы связываете их с ОДНОЙ ЖЕ основной лежащей в книге книгой.

Я объясню это более подробно здесь:

http://bretthargreaves.wordpress.com/2014/11/11/entity-framework-and-interface-issues/

...