2012-01-01 4 views
1

У меня есть следующие модели Person в моем слое UI MVC:Как карта DTO от EF к модели

public class Person 
{ 
    [Required] 
    public string FirstName { get; set; } 

    [Required] 
    public string LastName { get; set; } 

    public int PersonTypeID { get; set; } 

    [Required] 
    public string Phone { get; set; } 

    [Required] 
    public string Email { get; set; } 

} 

В моем слое данных, у меня есть класс с теми же именами свойств, но и другие метаданные (естественно,):

public partial class Person : EntityObject { ... } 

Как вернуть данные из моего уровня данных в моем слое MVC UI, не имея данных слоя знать о слое MVC UI?

Примечание: У меня также есть простой IPerson-интерфейс с теми же именами свойств.

ответ

4

Вы можете использовать AutoMapper для сопоставления между моделью домена и моделью просмотра. Уровень MVC знает о слое данных, но уровень данных не обязательно должен знать о слое MVC.

Вот общая картина:

public ActionResult Foo() 
{ 
    var person = _repository.GetPerson(); 
    var personViewModel = Mapper.Map<Person, PersonViewModel>(person); 
    return View(personViewModel); 
} 

и наоборот:

[HttpPost] 
public ActionResult Foo(PersonViewModel personViewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(model); 
    } 
    var person = Mapper.Map<PersonViewModel, Person>(personViewModel); 
    _repository.UpdatePerson(person); 
    return RedirectToAction("Success"); 
} 

Как вы можете видеть, что уровень данных не нужно ничего знать о слое MVC. Это уровень MVC, который должен знать о слое данных.

+1

Единственная проблема, которую я вижу с этим, если вы когда-нибудь понадобится, чтобы переключить ваша реализация данных (например, от EF до Linq to SQL). Теперь ваш слой MVC хочет объект Person, который связан исключительно с EF. –

+0

@BrianDavidBerman, ну нет чудесного решения. Лучше всего было бы иметь структуру ORM, которая не является навязчивой, и позволяет вам сопоставлять ваши фактические объекты домена, чтобы вы не получали какие-то автогенерированные и загрязненные классы. Насколько я знаю, это возможно с EF. Лучшее решение - иметь бизнес-объекты с чистым доменом, которые не являются специфическими для некоторых систем доступа к данным, но специфичны для бизнес-требований. –

1

Я бы предложил вам просмотреть структуру, такую ​​как automapper, которая дает вам возможность легко выполнять сопоставление объектов с объектами.

0

Другой вариант CX.Mapper очень проста в использовании и вам не нужно precofig карте:

[HttpGet] 
public ActionResult Edit(int id) 
{ 
    var item = this.db.Items.Find(id); 
    var model = CX.Mapper.Mapping.MapNew<Item, ItemDto>(item); 
    return View(model); 
} 

[HttpPost] 
public ActionResult Edit(ItemDto model) 
{ 
    if(Model.IsValid) 
    { 
    var item = this.db.Items.Find(ItemDto.Id); 
    CX.Mapper.Mapping.Map<ItemDto, Item>(model, item); 
    this.db.SaveChanges(); 
    return RedirectToAction("Index"); 
    } 
    return View(model); 
} 

Вы можете установить с NuGet

Смежные вопросы