ViewModel与相关对象

时间:2013-04-30 16:43:24

标签: c# asp.net-mvc entity-framework asp.net-mvc-4

相对较新的.Net MVC。被看似非常简单的问题所困扰。

我有一些彼此相关的对象。

(作为例子)

public class Asset{
  public int Id{get;set;}
  public AssetCategory AssetCategory {get;set;}
  public string Value {get;set;}
}

public class AssetCategory{
  public string Name{get;set;}
  public DateTime SomeDate{get;set;}
  public int Id{get;set;}
}

我想在我的View和pre中创建一个新的“Asset”对象,所以我创建一个带有AssetCategory集的空对象。然后将其作为该视图的模型传递。

我试过@Html.HiddenFor(m=>m.AssetCategory) 这显然是失败的,因为它不知道如何从该对象转换为字符串并返回。

如果我有@Html.HiddenFor(m=>m.AssetCategory.Id),那么我的ModelState有效,但没有将所有信息绑定到AssetCategory。

在这种情况下,我是否只需从数据库中获取任何分离对象的正确版本? 目前,我试图保存我的新资产。我收到错误,因为AssetCategory对象上的不可为空的DateTime无效。

3 个答案:

答案 0 :(得分:1)

如果您只需要服务器上的类别信息,那么是,在服务器上获取该类别信息并在保存之前附加到您的对象。

如果您的客户将更改它,您应该只在您的模型中包含AssetCategory,即。你有一个用户可以选择的下拉列表。在这种情况下,仅将ID和有效项列表添加到模型中。回传模型后,将其转换为需要保存的对象。

换句话说,将您必须保存的类保存到数据库,但创建一个单独的视图模型。

答案 1 :(得分:0)

如果您需要的只是Id,那么您的原始选项将起作用(但正如您所说的,仅基于已发布的返回数据而没有其他详细信息)。

@Html.HiddenFor(m=>m.AssetCategory.Id)

如果您想了解更多信息,请尝试使用EditorTemplate使其模块化。

@Html.EditorFor(m=>m.AssetCategory)

\视图\资产\ EditorTemplates \ AssetCategory.cshtml

@model AssetCategory
@Html.HiddenFor(m=>m.Id)
@Html.DisplayFor(m=>m.Name)

话虽这么说,你应该使用ViewModels这类东西而不是EntityModels。我建议将其保留为仅传回Id,但在回发后,在保存资产本身之前使用AssetCategoryId从数据库加载完整的资产类别信息。

答案 2 :(得分:-1)

对于性能,EF默认情况下不会将所有数据加载到模型中。所以,你必须像这样手动加载:

 public ActionResult MyAction(int id)
 {
    var asset = db.Assets.Single(a => a.Id == Id).Include(a => a.AssetCategory);

    return View(asset);
 }

Include方法会将相关对象加载到其模型中,因此您将获得所有属性,@Html.HiddenFor(m=>m.AssetCategory.Id)Id填充正确的数据。

请查看Loading Related Objects了解更多EF相关信息!

希望它对你有所帮助!