2009-09-20 4 views
5

Я проходил учебники (в частности, с использованием Linq-To-Entities), и я понимаю основные понятия, однако некоторые вещи дают мне проблемы.Является ли мое ASP.NET MVC-приложение структурированным правильно?

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

Для метода пост, обычный способ выполнения Crud ОПЕРАЦИЙ

entities.AddToTableSet(myClass); 
entities.SaveChanges(); 

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

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Add(int id, [Bind(Exclude = "Id")] ClassA classA, 
         [Bind(Exclude = "Id")]ClassB classB) 
{ 
    // Validation occurs here 

    if(!ModelState.IsValid) 
     return View(); 

    try 
    { 
     _someRepositoryOrService.Add(id, classA, classB); 
     return RedirectToAction("Index", new { id = id }); 
    } 
    catch(Exception ex) 
    { 
     // Logging and exception handling occurs here 
    } 
} 


public void Add(int id, ClassA classA, ClassB classB) 
{ 
    EntityA eA = new EntityA 
    { 
     // Set a bunch of properties using the two classes and 
     // whatever queries are needed 
    }; 

    EntityB eB = new EntityB 
    { 
     // Set a bunch of properties using the two classes and 
     // whatever queries are needed 
    }; 

    _entity.AddToEntityASet(eA); 
    _entity.AddToEntityBSet(eB); 
    _entity.SaveChanges(); 
} 

Я правильно справляюсь с этим, или я ухожу в раму? Я никогда не использую объект сущности напрямую, всякий раз, когда я запрашиваю его, я помещаю информацию, которая мне нужна в DTO, и основываю свои соображения на этом. То же самое происходит с созданием. Разрешено ли это или мое избегание использования сущностей, непосредственно идущих против цели использования структуры?

Edit: Я тоже волнуется по поводу такого подхода, поскольку он требует пустых конструкторов правильно делать запросы LINQ из-за это сообщение об ошибке:

только без параметров Конструкторов и Инициализаторов поддерживаются в LINQ к Entities ,

Это не имеет большого значения, так как мне редко нужна логика int конструкторов, но разве это проблема, когда у вас нет конструкторов и только публичных свойств?

+1

Объектконтекст, используемый Linq to Entities, использует отражение для создания объектов из сопоставления данных, поэтому важно, чтобы все сущности имели конструктор без параметров, поэтому его можно инициализировать плюс, если вы хотите иметь возможность сериализовать свои типы, тоже понадобится публичный конструктор – dmportella

ответ

4

_someRepositoryOrService.Add (id, classA, classB);

Я бы сказал, что вы связываете свои репозитории с презентационным слоем. Этого не должно быть. Ваши репозитории должны работать только с объектами.Далее, обратите внимание, как ваш метод Add

общественных недействительного Add (интермедиат идентификатор, ClassA CLASSA, ClassB ClassB)

разрывов разделение проблем (SoC). Он выполняет две задачи:

  1. карту просмотра данные в субъект
  2. сохранить в хранилище

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

Отметьте также этот отличный post от Jimmy Bogard (соавтор ASP.NET MVC In Action) о ViewModels. Это может помочь вам автоматизировать картографирование. Это также предлагает обратную технику - заставить ваши контроллеры работать с объектами, а не с ViewModels! Пользовательские фильтры действий и привязки к модели действительно являются ключом к устранению процедуры, которая на самом деле не принадлежит контроллерам, а скорее детали инфраструктуры между представлением и контроллером. Например, here, как я могу автоматизировать восстановление объектов. Here, как я вижу, какие контроллеры должны делать.

Цель состоит в том, чтобы сделать контент-концентраторы для управления бизнес-логикой, отложив в сторону все технические детали, которые не принадлежат вашему бизнесу. Это технические ограничения, о которых вы говорите в этом вопросе, и вы позволяете им втекать в ваш код. Но вы можете использовать инструменты MVC для перемещения на них уровня инфраструктуры.

UPDATE: Нет, репозитории не должны обрабатывать данные формы, вот что я подразумеваю под «связью с презентацией». Да, репозитории находятся в контроллере, но они не работают с данными формы. Вы можете (не то, чтобы вы должны) работать с формами «данные репозиториев» - то есть объекты - и это то, что делают большинство примеров, например. NerdDinner - но не наоборот. Это связано с общим правилом - более высокие уровни могут быть связаны с более низкими (представление в сочетании с репозиториями и сущностями), но никогда низкий уровень не должен быть связан с более высокими (объекты зависят от репозиториев, хранилищ зависят от модели модели и т. Д.).

Первый шаг должен быть сделан в репозитории, это правильно - за исключением того, что сопоставление от ClassX к EntityX не относится к этому шагу. Это картографическая забота - инфраструктура. См. Например this вопрос о сопоставлении, но, как правило, если у вас есть два уровня (UI и репозитории), они не должны заботиться о сопоставлении - служба-хранитель/помощник должен. Помимо блога Jimmy вы также можете прочитать ASP.NET MVC In Action или просто посмотреть на их CodeCampServer на то, как они выполняют сопоставление с интерфейсами IEntityMapper, переданными конструкторам контроллера (обратите внимание, что это более ручной и менее эффективный подход к AutoMapper от Jimmy Bogard).

Еще одна вещь. Читайте о разработке Driven Driven Design, ищите статьи, учитесь у них, но вам не обязательно следовать всем. Это рекомендации, а не строгие решения. Посмотрите, может ли ваш проект справиться с этим, посмотрите, можете ли вы его обработать и т. Д. Попытайтесь применить эти методы, поскольку они, как правило, превосходные и одобренные способы развития, но не воспринимайте их вслепую - лучше учиться на этом пути, чем применять то, что вы не понимаете.

+0

Для связывания репозиториев я не уверен, что вы имеете в виду, наличие репозитория в контроллере, по-видимому, является тем, что делает большинство учебников. Что касается первого шага, выполняемого на уровне презентации, не следует ли это делать в репозитории? Я думал, что целью репозиториев должно быть беспокойство по поводу обработки данных формы для преобразования базы данных? – Brandon

+0

Также благодарим вас за примеры и советы. У меня не было времени, чтобы на самом деле внести изменения, но это хороший толчок в правильном направлении. – Brandon

+0

См. Обновление. Я бы предложил рефакторировать медленно, например, сначала выполните _realEntityRepository.Add (EntityMapper.From (classA)); (или classA.MapToEntity()), а затем включить пользовательский ModelBinder (который является большой темой), затем добавить контейнер IoC (еще одна большая тема) и так далее. – queen3

4

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

Эти проблемы на самом деле не обязательно связаны с ASP.NET MVC. ASP.NET MVC не дает в основном никаких указаний о том, как сделать доступ к вашей модели/данным, и большинство примеров и руководств для ASP.NET MVC не являются достойными реализацией модели, а действительно просто минимальными образцами.

Кажется, что вы на правильном пути, продолжайте движение.

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

+0

Я действительно использую только инфраструктуру Entity, чтобы попробовать что-то новое. Я использую nHibernate. У вас есть предложения по улучшению генератора или структуры, которые я должен использовать? – Brandon

+0

Я не знаю ничего, что отлично подходит для ваших нужд. Некоторые из них являются коммерческими, а некоторые бесплатны. В определенном порядке: шаблоны T4, CodeSmith, LLBLGen Pro. –

+1

Это в основном очень хороший ответ (+1), но я не согласен, что он использует Entity Framework в качестве генератора кода. Что гораздо важнее, так это то, что он использует платформу Entity Framework для сопоставления своей базы данных в пространстве объектов. Это важно, даже если вы никогда не материализуете тип сущности; вы по-прежнему используете объекты сопоставления в своих запросах LINQ to Entities, когда вы проектируете их на другие типы. –

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