Entity Framework + POCO - PullRequest
       9

Entity Framework + POCO

8 голосов
/ 24 апреля 2009

Я создаю приложение WPF, используя шаблон MVVM. Наш стек выглядит так:

SQL Server 2008 -> Entity Framework

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

ViewModels использует DataFactory для CRUD, а xaml - это данные, привязанные к свойствам в POCO.

Все это прекрасно работает, но единственное, что я нахожу чем-то вроде раздражения, это фабрика данных. Мы копируем каждое свойство из объекта EF в объект POCO при выборе и наоборот при обновлении / вставке.

Есть ли способ автоматизировать этот процесс, как это делает Fluent для NHibernate, но с помощью Entity Framework?

Вот пример метода вставки в фабрику данных:

public void InsertCustomer(ref Manager.Model.Customer businessObject)
{
    var mgr = new Manager.Data.PersonData.PersonContext();

    var person = new Manager.Data.PersonData.Person();
    var customer = new Manager.Data.PersonData.Customer();

    customer.Comments = businessObject.Comments;
    customer.Company = businessObject.Company;
    customer.IsBusiness = businessObject.IsBusiness;
    customer.IsCompleted = businessObject.IsCompleted;
    customer.ModifiedBy = "someone";
    customer.ModifiedOn = DateTime.Now;
    customer.CreatedBy = "someone";
    customer.CreatedOn = DateTime.Now;

    person.Customer.Add(customer);
    person.FirstName = businessObject.FirstName;
    person.LastName = businessObject.LastName;
    person.Birthday = businessObject.Birthday;
    person.CreatedBy = "someone";
    person.CreatedOn = DateTime.Now;
    person.Gender = businessObject.Gender;
    person.MiddleInitial = businessObject.MiddleInitial;
    person.ModifiedBy = "someone";
    person.ModifiedOn = DateTime.Now;
    person.Nickname = businessObject.Nickname;
    person.Picture = "";
    person.Suffix = businessObject.Suffix;
    person.Title = businessObject.Title;

    mgr.AddToPeople(person);
    mgr.SaveChanges();
}

Было бы неплохо объявить некоторый класс, как это делает Fluent:

public class CatMap : ClassMap<Cat>  
{  
  public CatMap()  
  {  
    Id(x => x.Id);  
    Map(x => x.Name)  
      .WithLengthOf(16)  
      .Not.Nullable();  
    Map(x => x.Sex);  
    References(x => x.Mate);  
    HasMany(x => x.Kittens);  
  }  
}

Наконец, мой метод вставки будет выглядеть так:

public void InsertCustomer(ref Manager.Model.Customer businessObject)
{
    var mgr = new Manager.Data.PersonData.PersonContext();

    var person = new Manager.Data.PersonData.Person();
    var customer = new Manager.Data.PersonData.Customer();

    Something.Map(person, businessObject);
    Something.Map(customer, businessObject);  

    person.Customer.Add(customer);

    mgr.AddToPeople(newCustomer);
    mgr.SaveChanges();
}

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

Спасибо!

Ответы [ 2 ]

11 голосов
/ 01 мая 2009

Можете попробовать Automapper, у меня работает.

http://www.codeplex.com/AutoMapper

1 голос
/ 26 апреля 2009

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

Одна мысль, которая может быть интересной, - создать методы расширения функций вашей карты. Вы все равно создали бы класс Mapper, но каждый из методов карты выглядел бы как

    public static Person MapToPerson(this Manager.Model.Customer bizObject)
    {
        Person person = new Person();
        // mapping logic
        return person;
    }

Поскольку метод MapToPerson является методом расширения, а не методом в вашем классе bizObject, вы не нарушаете POCO. Но из-за синтаксического сахара метода расширения ваш метод InsertCustomer может иметь такой код:

    Customer customer = bizObject.MapToCustomer();
    Person person = bizObject.MapToPerson();
...