преобразование объекта POCO в бизнес-объект - PullRequest
1 голос
/ 16 апреля 2011

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

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

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

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?

Ответы [ 3 ]

10 голосов
/ 16 апреля 2011

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

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

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

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

Редактировать:

Хорошо.Вы можете использовать свои классы вместо сгенерированных объектов POCO.

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

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

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

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

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

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

1 голос
/ 17 апреля 2011

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

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

1 голос
/ 16 апреля 2011

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

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

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

например,

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 ничего не должен знать об этом.

...