Pregunta

Este problema ha sido que me condujo loco por varias horas, ahora...

En mi dominio, tengo 2 entidades que están relacionadas con cada uno de los otros Sku y Item.Cada sku puede tener muchos elementos.

public class Sku
{
    private readonly EntitySet<Item> items;
    public Sku()
    {
        items = new EntitySet<Item>(AttachItems, DetachItems);
    }
    public int SkuId { get; set; }
    public string LongDescription { get; set; }
    public EntitySet<Item> Items
    {
        get { return items; }
        set{ items.Assign(value);}
    }
    private void AttachItems(Item entity)
    {
        entity.Sku = this;
    }
    private static void DetachItems(Item entity)
    {
        entity.Sku = null;
    }
}

public class Item
{
    public Sku Sku { get; set; }
    public int ItemId { get; set; }
    public string Category { get; set; }
    public string Description { get; set; }
}

Estoy construyendo una página que le permitirá al usuario final para la actualización de algunos de los campos en el sku y algunos campos de cada elemento al mismo tiempo.

<% using (Html.BeginForm("Save", "Merchant", FormMethod.Post, 
       new { enctype = "multipart/form-data" })) { %>       
<fieldset>
    <legend>Sku</legend>
    <p><label for="SkuId">SkuId:</label>
       <%= Html.TextBox("SkuId", Model.SkuId, 
           new{@readonly="readonly",onfocus="this.blur();"}) %></p>
    <p><label for="LongDescription">LongDescription:</label>
       <%= Html.TextBox("LongDescription", Model.LongDescription) %></p>
</fieldset>
<% for (int i = 0; i < Model.Items.Count; i++) { %>       
<fieldset>
    <legend>Item</legend>
    <p><label for="ItemId">ItemId:</label>
       <%= Html.TextBox(string.Format("items[{0}].{1}", i, "ItemId"), 
           Model.Items[i].ItemId, 
           new { @readonly = "readonly", onfocus = "this.blur();" })%></p>
    <p><label for="Category">Category:</label>
       <%= Html.TextBox(string.Format("items[{0}].{1}", i, "Category"), 
           Model.Items[i].Category)%></p>
    <p><label for="Description">Description:</label>
       <%= Html.TextBox(string.Format("items[{0}].{1}", i, "Description"), 
           Model.Items[i].Description)%></p>
</fieldset>
<%} // for-loop %>
    <p><input type="submit" value="Save" /></p>
<%} // form %> 

Tengo algunas controlador de código que funciona a través de la aceptación de un Sku y un EntitySet de Item y, a continuación, asignar el Items a la Sku.

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Save(Sku sku, EntitySet<Item> items)
    {
        if (sku != null)
        {
            if (items != null)
            {
                sku.Items.Assign(items);
            }
        }

        // save Sku to repository ...
        // return Details view ...
    }

Esto funciona, sin embargo, me he dado cuenta de que hace dos viajes a través de la DefaultModelBinder para cada Item además de un viaje para el Sku.Cuando el Sku es obligado, el setter para Items se llama, y el ligante, incluso pasa en un hidratado Items colección con los valores correctos.Sin embargo, después de la llamada a items.Assign, Items.Count es 0.Esta es la razón por la que tengo que volver a asignar los elementos en el código de controlador.Yo estaba esperando los elementos para ser transferido a la Items la recolección por parte del cuaderno.Esto debería eliminar el viaje adicional por cada artículo, desde el items parámetro en mi método de controlador podría ser eliminado.¿Por qué no esta funcionando?

¿Fue útil?

Solución

Usted puede ser que necesite para crear un cuaderno de modelo personalizado para esto?

Otros consejos

Esperemos, yo soy la comprensión de que el problema correctamente...

En lugar de definir su Guardar acción con 2 parámetros, que han intentado definir tan solo con un solo parámetro, de tipo Sku?

Entonces usted desea volver a definir el elemento HTML controles similares a los del siguiente ejemplo...

<%=
    Html.TextBox
    (
        string.Format("sku.Items[{0}].{1}", i, "ItemId"), 
        Model.Items[i].ItemId, 
        new { @readonly = "readonly", onfocus = "this.blur();" }
    )
%>


De este modo, está poblando los artículos directamente en el Sku objeto en sí mismo.


Otra posible solución sería agregar un campo adicional a su clase de Elemento, tales como...

Int32 SkuId { get; set; }

De esta manera, se podría definir un nuevo campo oculto para cada elemento en su opinión de que sería auto-ligado a la SkuId de cada elemento en el controlador.

<%=
    Html.Hidden
    (
        string.Format("sku.Items[{0}].{1}", i, "SkuId"), 
        Model.Items[i].SkuId
    )
%>

Entonces, usted puede simplemente actualizar su colección de elementos de forma independiente de su Sku objeto.Independientemente de la manera en que usted ve, las dos colecciones tienen que decirle explícitamente Linq to SQL para actualizar el sku y elementos de todos modos.

También puede definir su propio cuaderno de clase, pero que es probablemente más trabajo de lo que vale en este caso.Simplemente siga las ASP.NET MVC convenciones, y creo que usted debería ser capaz de encontrar algo que funcione sin la sensación de que es un hack.

Yo tenía un problema similar donde EntitySets no estaban ligados correctamente en mi ViewModel.

Lo que hice fue crear otra propiedad llamada Mvc[YourEntitySetPropertyName], como una lista genérica, que se envuelve alrededor de los campos privados de la EntitySet:

public List<InvoiceLineItem> MvcInvoiceLineItemList
    {
        get { return _invoiceLineItemList.ToList(); }
        set { _invoiceLineItemList.AddRange(value); }
    }

A continuación, he usado la que, en lugar de la EntitySet propiedad en mi punto de vista marcado.

No habrá ninguna necesidad de pasar los artículos en su método de controlador de firma que acaba de pasar el Sku en ese punto:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Save(Sku sku)
{
    if (sku != null)
    {
       // save Sku to repository ...
       // return Details view ...
    }

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top