C# 使用MVC 3和EF4中的viewModel创建和编辑视图的复杂数据库结构

C# 使用MVC 3和EF4中的viewModel创建和编辑视图的复杂数据库结构,c#,asp.net-mvc-3,entity-framework-4,razor,viewmodel,C#,Asp.net Mvc 3,Entity Framework 4,Razor,Viewmodel,我在想如何处理这件事时遇到了麻烦。任何帮助都将不胜感激。甚至是一个适合我需要的更好结构的建议:在一个类别中构造类别项,该类别具有如何在类别项属性列表中的说明。 除其他外,它还用于生成用于创建和编辑项目的表单 长话短说:我需要知道我是否做对了,或者是一种更好的(可能是自动的)处理方式,而不会破坏整个应用程序。 . . 我正在VWD Express 2010的Win7 64位机器上使用MySQL 5,并安装了所有MySQL驱动程序(ODBC和.NET特定的提供程序,最后一个与ASP.NET 4不

我在想如何处理这件事时遇到了麻烦。任何帮助都将不胜感激。甚至是一个适合我需要的更好结构的建议:在一个类别中构造类别项,该类别具有如何在类别项属性列表中的说明。

除其他外,它还用于生成用于创建和编辑项目的表单

长话短说:我需要知道我是否做对了,或者是一种更好的(可能是自动的)处理方式,而不会破坏整个应用程序。 .
.

我正在VWD Express 2010的Win7 64位机器上使用MySQL 5,并安装了所有MySQL驱动程序(ODBC和.NET特定的提供程序,最后一个与ASP.NET 4不兼容)。这里出现了另一个问题,但可能是另一个问题的目标:我正在编写我的所有模型,因为MySql和LINQtoSQL不兼容(我可以想象为什么,但不确定)。 .
.

回到真正的话题:

@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);
}
我的模型是:

  • 类别
    -它们是主要实体,具有名称属性、一组
    类别临时属性
    实体和一组
    项目
    实体
  • CategoryItemProperty
    -具有名称和一些其他属性的实体,这些属性规定了该类别中的
    项的方式(字段大小、掩码、输入限制等)
    
  • -其属性基于类别属性的实体
  • 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; }
}
.
.

到目前为止,我想到的是创建一个
ViewModel
,将类别信息及其项属性集合传递到创建和编辑视图,并通过
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
生成字段并将信息存储在
项目
对象及其
项目属性
对象中的字段值时,如何处理这种情况?

.
.

请注意:所有这些代码仅供示例使用。我的代码与此类似,但它由特定的控制器和CRUD类别和CategoryItemProperty的特定视图处理,我对此没有问题

.
.


很抱歉,这篇文章太长了。我试着尽可能地说清楚。如果您需要更多信息,请发表评论。

好的,rcdmk!首先,我的英语很糟糕,我在这里只是想和大家分享我的一些经验

我曾经用MVVM(WPF)+EF4+T4构建过这样一个复杂的软件来生成POCO,我处理Microsoft Blend来处理客户端和viewmodels之间的操作、绑定等

太棒了!我希望我帮助了你

附言:
我不知道Blend是否支持ASP.Net,但是通过延迟加载创建POCO(Viewmodel)可以在某些方面帮助你

据我所知,Category和相应的CategoryPropertyItems描述了如何创建项目。简单地说,Category是一种抽象形式,而item和item属性是具体的(因为item属性具有Value属性)。所以,在Item/createaction(GET)中,您可以使用Category和CategoryPropertyItems构建项及其属性

公共项目生成(类别) { 项目=新项目(); 项目.类别=类别; item.ItemId=

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

        return item;
    }
在索引/创建操作的结果中,您可以仅使用此项对象,也可以将项放入ViewModel

在视图中,可以直接绑定到模型(项)属性

这个链接可以帮助你


在缺少帮助的情况下,我选择使用我已有的解决方案,直到我可以重新启用它为止(很快,因为我将不得不添加更多功能)重构我所有的代码,试图找到更好的方法。

不知何故,在这么多的文本中,我丢失了你的问题,那么问题是什么?我编辑了这个问题,让它更清楚。看起来你正在尝试构建一个web表单框架,比如wufoo或其他什么。你提到它有点糟糕,这很有意义。我假设您使用的框架旨在对实体及其属性进行静态建模。但您需要做的是创建一个完全动态的UI和模型引擎……这让我想起了SQL Server中的EAV模式,在这种情况下,很难查询这些数据。我确信,只要付出足够的努力,这是可行的,但您可能会想到您的Web窗体定义为文档,考虑文档数据库而不是关系数据库。祝您好运!谢谢。看来我现在必须继续我的解决方案。我可以考虑在这个案例中创建Mango数据库,但是所有其他功能都已经在MySQL服务器上运行。无论如何,我将拭目以待,看看有没有人。关于我的问题,我想一瓶威士忌比混合表达更能解决问题。对不起,我的英语也不是很好,我不知道你想说什么,但我想这是关于使用T4模板生成视图的。如果我没有抓住要点,请纠正我。只需在StackO或google f上搜索这里或者:实体框架+T4+Poco您将有足够的资源来更清晰地重新定义