2010-10-01 51 views
3

如果有几个linqTOsql对象,我试图通过窗体进行编辑。为什么不是MVC绑定我的嵌套集合?

首先,有个Stream类:

[Table] 
public class Stream 
{ 
    [HiddenInput(DisplayValue = false)] 
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
    public long StreamID { get; set; } 

    /*other properties removes for brevity*/ 

    // relationship (one stream to many Stream2FieldTypes) 
    // uses EntitySet<Stream2FieldTypes> and OtherKey for the FK in Stream2FieldTypes 
    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes; 
    [System.Data.Linq.Mapping.Association(Storage = "_Stream2FieldTypes", OtherKey = "StreamID")] 
    public EntitySet<Stream2FieldTypes> Stream2FieldTypes 
    { 
     get { return this._Stream2FieldTypes; } 
     set { this._Stream2FieldTypes.Assign(value); } 
    } 

} 

然后有Stream2FieldTypes类:

[Table] 
public class Stream2FieldTypes 
{ 
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
    public long s2fID { get; set; } 

    /*other properties removed for brevity*/ 

    [Column] 
    public long StreamID { get; set; }  // FK 




    // relationship (one Stream2FieldTypes to Streams) 
    private EntitySet<Stream> _Stream; 
    [Association(Storage = "_Stream", ThisKey = "StreamID")] 
    public EntitySet<Stream> Stream 
    { 
     get { return this._Stream; } 
     set { this._Stream.Assign(value); } 
    } 
} 

我用linqTOsql库来获得这些对象,并将它们发送到这样的观点:

public ActionResult StreamEdit(long id) 
    { 
     Genesis.Domain.Entities.Stream stream = genesisRepository.Streams.FirstOrDefault(x => x.StreamID == id); 

     return View(stream); 
    } 

所有东西都发送到视图没有问题...但是当视图上的表单被提交时,Stream.Stream2FieldTypes由于某种原因而丢失。我赶上表单提交这个动作:

[HttpPost] 
    public ActionResult StreamEdit(long id, Genesis.Domain.Entities.Stream form) 
    { 

      return View(form); 
    } 

和View是没有Stream2FieldTypes集合。

的观点写Stream2FieldTypes这样的:

<% for (int i = 0; i < (Model.Stream2FieldTypes != null ? Model.Stream2FieldTypes.Count() : 0); i++) %> 
<% { %> 
    <div class="ListItem"> 
     Label: <%: Html.EditorFor(x => x.Stream2FieldTypes[i].s2fLabel, new { style="width:100px" })%> 
     Required: <%: Html.EditorFor(x => x.Stream2FieldTypes[i].s2fIsRequired)%> 
     Field Type ID": <%: Html.EditorFor(x => x.Stream2FieldTypes[i].FieldTypeID, new { style="width:20px;" })%> 
     Stream ID: <%: Html.EditorFor(x => x.Stream2FieldTypes[i].StreamID) %> 
</div> 
<% } %> 

为什么没有在MVC默认模型绑定正确地结合嵌套集合?

回答

2

我会建议你使用POCO视图模型而不是那些混乱的模型类。他们不适应观点,很难与之合作。试图绑定到LINQ特定的集合,如EntitySet<T>不是一个好主意。这种使用编辑模板的方式实际上可能会起作用,但即使这种方法奏效,在介绍适当的视图模型之前也应该考虑它是一种临时解决方案。

在你的主观点与此更换循环:

<%: Html.EditorFor(x => x.Stream2FieldTypes) %> 

,然后添加一个强类型的~/Views/Home/EditorTemplates/Stream2FieldTypes.ascx局部视图:

<%@ Control 
    Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<SomeNs.Stream2FieldTypes>" 
%> 
<div class="ListItem"> 
    Label: 
    <%: Html.EditorFor(x => x.s2fLabel, new { style="width:100px" }) %> 

    Required: 
    <%: Html.EditorFor(x => x.s2fIsRequired) %> 

    Field Type ID: 
    <%: Html.EditorFor(x => x.FieldTypeID, new { style="width:20px;" })%> 

    Stream ID: 
    <%: Html.EditorFor(x => x.StreamID) %> 
</div> 

正常情况下应该采取产生正确的输入名称的照顾,但是为了避免人们以此为例,我再次重复使用适当的视图模型。

+0

感谢您的提示。我没有考虑使用编辑模板。对于POCO对象...无论编辑器是否适用于,我都应该将我的linqTOsql对象复制为普通旧C#对象?当然,我对这个级别的数据绑定是新手,但基本上有两个相同结构的副本似乎是一个非常糟糕的主意。 – quakkels 2010-10-01 22:01:36

+0

@quakkels,它是不一样的结构。视图模型是适应视图的类。对于单个模型类,您可以拥有不同的多视图模型类,例如“Stream”类。例如,您可以为编辑视图创建一个视图模型,并为显示视图创建另一个视图模型,因为不同的字段等。为了简化视图模型和模型类之间的映射,您可以使用[AutoMapper](http:// automapper)。 codeplex.com/)。这个想法是永远不会将真实模型传递给视图,而是为此特定视图提供专门定制的视图模型类。 – 2010-10-01 22:04:43

+0

由于视图模型适合视图使用它们会导致视图中非常干净的代码,因为视图模型已经拥有了所需的所有内容,并且您不必在标记中编写丑陋的循环,条件等以意大利面代码。你不应该担心重复视图模型中的一些属性,这就是这些类的意图。 – 2010-10-01 22:06:12