Сложная структура базы данных для создания и редактирования представлений с использованием viewModel в MVC 3 с EF4 - PullRequest
1 голос
/ 07 января 2012

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

Это используется, помимо прочего, для динамического создания форм для создания и редактирования элементов.

Короче говоря: Мне нужно знать, правильно ли я это делаю или лучше (возможно, автоматизированный) способ справиться с этим, не ломая целое приложение. .
,

Я работаю с MySQL 5 в VWD Express 2010 на 64-битной машине Win7 со всеми установленными драйверами MySQL (поставщик ODBC и .NET, последний не совместим с ASP.Net 4). Другая проблема возникла здесь, но может быть целью для отдельного вопроса: я пишу все свои модели, потому что MySql не совместим с Linq to SQL (я могу представить почему, но не уверен). .
,

Возвращаясь к реальной теме:

Мои модели:

  • Category - Их основная сущность со свойством name, коллекцией CategoryItemProperty сущностей и коллекцией Item сущностей;
  • CategoryItemProperty - объект с именем и некоторыми другими свойствами, которые определяют, каким может быть Items в этой категории (размер поля, маска, ограничение ввода и т. Д.);
  • Item - объект, свойства которого основаны на свойствах категории;
  • ItemProperty - Свойства элементов (размер поля, маска, ограничение ввода и т. Д.)

Код примерно такой:

public class Category
{
    public int CategoryId { get; set }
    public string Description { get; set }
    //...
    public virtual List<CategoryItemProperty> ItemProperties { get; set; }
}

public class CategoryItemProperty
{
    public int CategoryItemPropertyId { get; set; }
    public string Label { get; set; }
    public string Name { get; set; }
    public int Size { get; set; }
    public int MaxLenght { get; set; }
    //...
    public virtual Category Category { get; set; }
}

public class Item
{
    public int ItemId { get; set; }
    public string Description { get; set; }
    public int CategoryId { get; set; }
    //...
    public virtual Category Category { get; set }
    public virtual List<ItemProperty> Properties { get; set; }
}

public class ItemProperty
{
    public int ItemPropertyId { get; set; }
    public int ItemId { get; set; }
    public int CategoryItemPropertyId { get; set; }
    public string Value { get; set; }
    //...
    public virtual Item Item { get; set; }
    public virtual CategoryItemProperty CategoryItemProperty { get; set; }
}

.
,

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

.
,

Более подробный пример: Создайте простую контактную форму:

Мы создаем Category с некоторой спецификацией поля:

var category = new Category() { Description = "Simple Contact Form" };

MyEntitySet.Categories.Add(category);
MyEntitySet.SaveChanges();

//...

var name = new CategoryItemProperty() { Label = "Name", Size = 50, MaxLength = 50 };
var message = new CategoryItemProperty() { Label = "Message", Size = 50, MaxLength = 255 };

category.ItemProperties.Add(name);
category.ItemProperties.Add(message);

MyEntitySet.Entry(category).State = EntityState.Modified;

MyEntitySet.SaveChanges();

.
,

До сих пор я придумал создание ViewModel для передачи информации о категории и ее коллекции свойств элемента в представления Create и Edit и выполнение цикла по ItemProperties для генерации полей и работы в ItemController, получение FormCollection и генерацию Item и его ItemProperty s объектов и сохранение их в базе данных. Но этот процесс ужасен и болезненен:

.

Элементы / Создать вид:

@model MyApp.Models.CategoryItemModelView

@Html.EditorFor(m => m.Description);    
...
@foreach(var property in Model.ItemProperties)
{
    <label>@property.Label</label>
    <input type="text" name="@property.Name" size="@item.Size" maxlength="@item.MaxLength" />
}

В контроллере:

// GET: /Items/Create/5
public ActionResult Create(int id)
{
   var categoryItemModelView = new CategoryItemModelView();
   categoryItemModelView.Populate(id); // this method maps the category POCO to the ViewModel

   return View(categoryItemModelView);
}

// POST: /Items/Create/5
[HttpPost]
public ActionResult Create(int id, FormCollection formData)
{
    if (ModelState.IsValid)
    {
       var category = MyEntitySet.Categories.Find(id);

       var item = new Item
       {
           CategoryId = id,
           Description = formData["Description"],
           // ...
           Category = category
       };
       MyEntitySet.Items.Add(item);

       foreach(var property in category.ItemProperties)
       {
           var itemProperty = new ItemProperty
           {
               ItemId = item.ItemId,
               CategoryItemPropertyId = property.Id,
               Value = form[property.Name],
               // ...
               Item = item,
               CategoryItemProperty = property
           };

           MyEntitySet.ItemProperties.Add(itemProperty);
       }

       MyEntitySet.SaveChanges();
       return RedirectToAction("Index");
    }

    // Here I don't know how to return the typed data to the user (the form returns empty)
    var categoryItemModelView = new CategoryItemModelView(id);
    categoryItemModelView.Populate(id); // this method maps the category POCO to the ViewModel

    return View(categoryItemModelView);
}

.
,

Моя проблема возникает при создании действий Create и Edit и их соответствующих представлений (см. Выше, как я делаю это прямо сейчас). Как справиться с этим случаем, когда мне нужно использовать Category.ItemProperties для генерации полей и сохранения информации в объекте Item, а значения полей в его ItemProperty объекте?

.
,

Обратите внимание: Весь этот код предназначен только для примера. Мой код похож, но он обрабатывается определенным контроллером и определенными представлениями для CRUD Categories и CategoryItemProperties, и у меня нет проблем с этим.

.
,

Извините за этот длинный текст. Я старался быть максимально ясным. Если вам нужна дополнительная информация, оставьте комментарий, пожалуйста.

Ответы [ 3 ]

0 голосов
/ 17 января 2012

Как я понимаю, Category и соответствующие CategoryPropertyItems описывают, как будет создаваться Item. Просто Категория рисует абстрактную форму, а свойства элемента и элемента являются конкретными (поскольку свойство элемента имеет свойство Value). Таким образом, в Item / Create Action (GET) вы можете создать элемент и его свойства, используя Category и CategoryPropertyItems.

Публичный предмет сборки (категория категории) { Предмет вещь = новый предмет (); item.Category = категория; item.ItemId = ...

        foreach(var categoryItemProperty in category.ItemProperties)
        {
            ItemProperty itemProperty = new ItemProperty();
            itemProperty.Item = item;
            itemProperty.CategoryItemProperty = categoryItemProperty;
            itemProperty.ItemPropertyId = ... 
        }

        return item;
    }

В результате действия Index / Create вы можете использовать либо только этот объект Item, либо вы можете поместить элемент во ViewModel.

В View вы можете привязать напрямую к свойствам модели (Item).

Эта ссылка может вам помочь.

Редактирование и привязка вложенных списков с помощью ASP.NET MVC 2 привязка модели к списку

0 голосов
/ 05 марта 2012

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

0 голосов
/ 16 января 2012

Хорошо, rcdmk!Прежде всего, мой английский ужасен, и я здесь, чтобы просто поделиться с вами своим небольшим опытом.

В прошлом я создавал такое сложное программное обеспечение с MVVM (WPF) + EF4 + T4 для генерации POCO , и я имею дело с Microsoft Blend для обработкис действиями, привязками и так далее между клиентом и моделями представления!

это отлично работает!я надеюсь, что помог вам!

ps: я не знаю, поддерживает ли Blend ASP.Net, но создание POCO (Viewmodel) с отложенной загрузкой может помочь вам где-нибудь!

...