преобразование POCO-объекта в коммерческое предприятие

Я готов интегрировать структуру сущностей в качестве уровня данных.

Я следил за статьями и сгенерировал объекты poco, используя этот учебник: http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx

У меня есть свои бизнес-объекты. Вот мой бизнес-объект Brach:

public class Branch
{
    public long BranchId { get; private set; }
    public string BranchName { get; set; }
    public string BranchCode { get; set; }

    public Branch() { }

    public void InsertBranch(Guid companyId)
    {
        using (var ctx = new Entities.Entities())
        {
            var branch = new T_STF_BRANCH() //This is generated POCO object
            {
                company_id = companyId,
                branch_name = BranchName,
                branch_code = BranchCode
            };
            ctx.T_STF_BRANCH.AddObject(branch);
            ctx.SaveChanges();
        }
    }

    public static IList<Branch> GetBranchesList(Guid companyId, long? branchId,
        string branchName)
    {
        using (var ctx = new Entities.Entities())
        {
            var branchs = ctx.T_STF_BRANCH.Where(x =>
                x.is_deleted == false &&
                (branchId == null || x.branch_id == branchId) &&
                (branchName == null || x.branch_name.Contains(branchName))).ToList();
        }
        //HERE I NEED SOMEHOW CONVERT THE POCO ENTITIES INTO MY BUSINESS ENTITIES...
    }
}

Я не знаю, как преобразовать объект POCO в свой бизнес.
Где мне поместить преобразование из POCO в POCO?


person Naor    schedule 16.04.2011    source источник


Ответы (3)


ИМХО это слишком сложно. Почему у вас есть сущность POCO для сохранения и отдельный объект для работы с данными, загруженными в сущность POCO? Похоже, ваше приложение перестроено.

ORM означает объектно-реляционное отображение. Это означает отображение между миром отношений и миром объектов. Обычно это также можно перевести как отображение между базой данных и вашими бизнес-объектами. Таким образом, вы должны использовать свои объекты POCO в качестве бизнес-объектов. В этом весь смысл использования POCO. Если вы не хотите использовать их в качестве бизнес-объектов, они вам не нужны, и вы можете напрямую использовать объекты сущностей по умолчанию.

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

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

Изменить:

Что ж. Вы можете использовать свои классы вместо сгенерированных сущностей POCO.

Один из способов - отказаться от EFv4 и EDMX и проверить новый EFv4.1 и его новый свободный API (также известный как code-first) для сопоставления. Это целиком для отдельного вопроса или просто воспользуйтесь поиском здесь, на SO.

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

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

EDMX состоит из трех слоев:

  • SSDL - описание базы данных. Это почти всегда создается, и вы не можете изменить его прямо в дизайнере.
  • CSDL - описание сущностей, которые должны совпадать с вашими бизнес-объектами. Это то, что вы изменяете в дизайнере. Вы можете переименовать поля как хотите.
  • MSL - соответствие между SSDL и CSDL. Если вы откроете контекстное меню любого объекта в дизайнере, вы увидите сопоставление таблиц. Откроется окно с определением сопоставления между CSDL и SSDL.

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

person Ladislav Mrnka    schedule 16.04.2011
comment
+1 Согласен. Я не вижу необходимости их разделять. Это также причинит вам серьезную боль, когда вы начнете загружать отношения и т. Д., Вы в конечном итоге создадите свою собственную ленивую загрузку и т. Д., Что является одной из основных функций файла или / m. - person Brook; 16.04.2011
comment
@ Ладислав Мрнка: У меня уже есть бизнес. Все мои приложения написаны с их помощью. Поэтому я не могу использовать объекты POCO в качестве бизнес-объектов. С другой стороны, Мои бизнес-объекты имеют наследование, и они являются сложными объектами, в отличие от POCO. Я не уверен, что могу использовать их вместо POCO. Приведу пример. - person Naor; 17.04.2011
comment
@Naor: Я отредактировал свой ответ. Это слишком много, чтобы дать вам пример. Вы должны показать конкретную проблему, что-то конкретное, что вы не знаете, как сопоставить ее, чтобы получить образец. - person Ladislav Mrnka; 17.04.2011
comment
@ Ладислав Мрнка: Спасибо за ответ. Можете ли вы взять пример из моего следующего вопроса (stackoverflow.com/questions/5690208/) в качестве образца? - person Naor; 17.04.2011
comment
@ Ладислав Мрнка: Я дважды прочитал ваш ответ, но до сих пор не понимаю. Как я могу сопоставить БД с моими объектами? изменение члена в edmx по-прежнему будет отображать поле с новым именем члена? - person Naor; 17.04.2011
comment
@ Ладислав Мрнка: Большое спасибо! У меня есть еще вопросы, которые я задам позже, но вы сумели пролить свет на этот процесс. - person Naor; 17.04.2011
comment
@LadislavMrnka Если POCO - это бизнес-объекты (бизнес-уровень), то как в него вписывается шаблон репозитория? Может ли архитектура быть такой: DB- ›DAL (EF) -› BLL (POCO) - ›Репозиторий / Единица работы-› UI (например, MVP)? Не могли бы вы пролить свет? - person Prokurors; 18.10.2013
comment
@LadislavMrnka Где классы Business Layer / POCO подходят для этой архитектуры? - person Prokurors; 18.10.2013

Вот пара возможностей, если я вас правильно понимаю.

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

Во-первых, в ваших бизнес-объектах создайте конструктор, который принимает ваш объект POCO в качестве параметра, а затем настройте каждое свойство.

e.g.

public Branch (POCO poco)
{
  Name = poco.Name;
  Zip = poco.Zip;
}

Другой вариант - использовать такой инструмент, как AutoMapper.

Это поможет вам автоматически сопоставить (отсюда и название;)) два объекта.

Я мог бы предложить одну вещь - не помещать Branch.GetListOfBranches (), а придумать такой класс, как DataLayer.cs или что-то в этом роде, поместив туда как можно больше логики вашего запроса. Таким образом, у вас не будет отдельных объектов, знающих о контексте ваших данных, а когда вам нужно внести изменения, останется меньше мест, куда их можно было бы внести.

У нас есть база данных Sales, а наш класс - SalesDb. Затем мы используем этот класс для получения необходимых нам сущностей. Так что мы можем сделать SalesDb.GetLeads() или даже SalesDb.GetLeads(Filter f), чтобы отфильтровать то, что нам не нужно. Теперь SalesDb контролирует контекст, и моему классу Leads не нужно ничего об этом знать.

person taylonr    schedule 16.04.2011
comment
Действительно ли ваш класс SalesDb является классом репозитория? - person Naor; 16.04.2011
comment
Более-менее да. Мы написали несколько общих методов, чтобы мы могли выполнять фильтрацию и сортировку в репозитории. У нас есть Filter ‹T›, где T может быть любой из наших моделей db (мы определили его через интерфейсы) - person taylonr; 16.04.2011

Если вы используете POCO в качестве контракта с внешними данными, вы можете захотеть, чтобы ваша модель предоставляла вам разные сущности / классы, чтобы предотвратить слабую связь между вашими внешними контрактами и тем, как работает ваше приложение.

При извлечении контракта данных вы можете извлечь соответствующую сущность из контекста, а затем ввести значения из контракта данных в сущность / сущности с помощью такого инструмента, как ValueInjecter.

person Danny Varod    schedule 16.04.2011