0

Ich verwende die erste Methode der Datenbank. Ich habe ein einzelnes Formular, wo Daten eingegeben werden. Daraus werden ein neuer "Formulareintrag", ein neuer Kunde und 3 neue Adressen erstellt. Dem Kunden sind 2 Adressen zugeordnet, 1 Adresse ist dem Formulareintrag als Ganzes zugeordnet und der Kunde ist dem Formulareintrag zugeordnet.ASP.NET MVC EntityFramework So speichern Sie neues Objekt zusammen mit mehreren untergeordneten Objekten in Erstellen

Die Frage (Revision 2): Wie wird man in der Regel über die Vorbereitung Felder gehen, die Objekte verweisen, die gleichzeitig erstellt werden soll - „Hey, diese ID-Felder werden hier Objekte gleichzeitig aus dem gleichen erstellt Referenz , aktueller Datensatz, aus dem du gebaut wurdest "?

(

d Wie würde man normalerweise so etwas wie die in MVC Folgendes tun:

1) erstellen jede der drei Adressen als neue Adressen;

2) verknüpfen Sie 2 von ihnen mit einem neuen Kunden über checkoutForm.Customer.HomeAddressId und checkoutForm.Customer.MailingAddressId;

3) verbinden Sie die andere mit checkoutForm.PlaceOfUseAddressId selbst;

4) speichern Sie den Kunden; dann

5) den Kunden mit checkoutForm.CustomerId verbinden; und schließlich

6) speichern Sie die checkoutForm selbst,

während nicht ModelState.IsValid falsch in der Zwischenzeit machen, weil checkoutForm.CustomerId und jede x.AddressId erforderlich sind, aber zunächst null?

)

Verweise auf etwas, das ein Verfahren für die gleichzeitige Erstellung mehrerer abhängigen Objekte wie dieses wäre fantastisch erklärt!


Edit: Ich entfernte die Bind-Attribut aus dem Parameter für Create(), und das macht alle Daten in die richtigen Felder ziehen. Die Dropdown-Listen greifen ihre jeweilige StateId richtig auf.

Gegenwärtig meldet ModelState.IsValid beim Übermitteln false. Die erforderlichen IDs der untergeordneten Objekte sind null und so (was sinnvoll ist, weil ich versuche, herauszufinden, wie man .NET erkennt - hier ist eine Objektverknüpfung, die erstellt wird, sobald wir die Daten haben).


Edit2: verfeinerte ich die Frage noch einmal, jetzt, wo ich bin immer näher zu dem, was ich brauche eigentlich zu beheben: ModelState.IsValid == falsch, weil die zugehörigen IDs für checkoutForm und Kunden, den Bezug Abhängigkeiten sind null.


Darstellung des Modells hinter dieser Form: Entity Framework model diagram

Hier ist die Form selbst. Page containing form

(Beachten Sie die 2 Dropdownlists Alles andere ist eine Textbox für Streicher, Ints, oder Dates)

Was ich bisher für den Controller habe (nicht viel darüber hinaus, was das Gerüst geschaffen hat):

// GET: CheckoutForms/Create 
public ActionResult Create() 
{ 
    ViewBag.HomeStateList = new SelectList(db.RT_STATE_LIST, "ST_SEQ", "ST_ABBR", 2); 
    ViewBag.MailingStateList = new SelectList(db.RT_STATE_LIST, "ST_SEQ", "ST_ABBR", 2); 
    return View(); 
} 

// POST: CheckoutForms/Create 
[HttpPost] 
[ValidateAntiForgeryToken] 
// public ActionResult Create([Bind(Include = "Customer.FirstName,Customer.LastName,VacuumNumber,Customer.Phone,Customer.DriversLicense,Customer.HomeAddress.Street,Customer.HomeAddress.City,Customer.HomeAddress.StateId,Customer.MailingAddress.Street,Customer.MailingAddress.City,Customer.MailingAddress.StateId,Customer.MailingAddress.PostalCode,PlaceOfUseAddress.Street,PlaceOfUseAddress.City,PlaceOfUseAddress.StateId,PickupDate,DueDate,ReturnedDate,EnteredBy,EnteredDate,ModifiedBy,ModifiedDate")] CheckoutForm checkoutForm) 
public ActionResult Create(CheckoutForm checkoutForm) 
{ 
    if (ModelState.IsValid) 
    { 
      checkoutForm.PlaceOfUseAddress.StateId = 1; 

      // !!! Need to be given correct value once authorization is set up. 
      checkoutForm.EnteredBy = -1; 
      checkoutForm.ModifiedBy = -1; 
      checkoutForm.EnteredDate = System.DateTime.Now; 
      checkoutForm.ModifiedDate = System.DateTime.Now; 

      // ??? db.Addresses.Add(checkoutForm.PlaceOfUseAddress); 
      // ??? db.Addresses.Add(checkoutForm.Customer.HomeAddress); 
      // ??? db.Addresses.Add(checkoutForm.Customer.MailingAddress); 
      // ??? db.SaveChanges(); 
      // ??? checkoutForm.PlaceOfUseAddressId = checkoutForm.PlaceOfUseAddress.AddressId; 
      // ??? checkoutForm.Customer.HomeAddressId = checkoutForm.Customer.HomeAddress.AddressId; 
      // ??? checkoutForm.Customer.MailingAddressId = checkoutForm.Customer.MailingAddress.AddressId; 
      // ??? db.Customers.Add(checkoutForm.Customer); 
      // ??? db.SaveChanges(); 
      db.CheckoutForms.Add(checkoutForm); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 

     ViewBag.HomeStateList = new SelectList(db.RT_STATE_LIST, "ST_SEQ", "ST_ABBR", checkoutForm.Customer.HomeAddress.StateId); 
     ViewBag.MailingStateList = new SelectList(db.RT_STATE_LIST, "ST_SEQ", "ST_ABBR", checkoutForm.Customer.MailingAddress.StateId); 
     return View(checkoutForm); 
} 

Schließlich sind hier die Formelemente aus der Sicht (mit allem anderen gezupft:

@using (Html.BeginForm()) 
{ 
    @Html.HiddenFor(model => model.CustomerId) 
    @Html.HiddenFor(model => model.PlaceOfUseAddressId) 
    @Html.HiddenFor(model => model.Customer.HomeAddressId) 
    @Html.HiddenFor(model => model.Customer.MailingAddressId) 
    @Html.HiddenFor(model => model.EnteredBy) 
    @Html.HiddenFor(model => model.EnteredDate) 
    @Html.HiddenFor(model => model.ModifiedBy) 
    @Html.HiddenFor(model => model.ModifiedDate) 


    <!-- Name and Vacuum Number --> 
    @Html.EditorFor(model => model.Customer.FirstName, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.Customer.LastName, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.VacuumNumber, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    <!-- Driver's License --> 
    <!-- Phone Number --> 
    @Html.EditorFor(model => model.Customer.Phone, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.Customer.DriversLicense, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    <!-- Place of Use Address --> 
    @Html.EditorFor(model => model.PlaceOfUseAddress.Street, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.PlaceOfUseAddress.City, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    <!-- Customer's Home Address --> 
    @Html.EditorFor(model => model.Customer.HomeAddress.Street, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.Customer.HomeAddress.City, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.DropDownListFor(model => model.Customer.HomeAddress.StateId, ViewBag.HomeStateList as SelectList, htmlAttributes: new { @class = "form-control checkout" }) 

    <!-- Customer's Mailing Address --> 
    @Html.EditorFor(model => model.Customer.MailingAddress.Street, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.Customer.MailingAddress.City, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.DropDownListFor(model => model.Customer.MailingAddress.StateId, ViewBag.MailingStateList as SelectList, htmlAttributes: new { @class = "form-control checkout" }) 

    @Html.EditorFor(model => model.Customer.MailingAddress.PostalCode, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    <!-- Dates Picked Up, Due, and Returned --> 
    @Html.EditorFor(model => model.PickupDate, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.DueDate, new { htmlAttributes = new { @class = "form-control checkout" } }) 

    @Html.EditorFor(model => model.ReturnedDate, new { htmlAttributes = new { @class = "form-control checkout" } }) 
} 
+1

Entfernen Sie dieses schreckliche '[Bind]' - Attribut und verwenden Sie ein Ansichtsmodell zum Bearbeiten Ihrer Daten (mit einer flachen Struktur und einschließlich Eigenschaften für Sie 'SelectLists') –

+0

Meinst du" View Model "wie in MVVM? Oder eine Art von Klasse, die (offensichtlich) in MVCs Modellen zu finden ist? – GG2

+0

Eine gezielte Frage per Post bitte. Das erhöht Ihre Chancen auf gezielte Antworten. –

Antwort

0

es herausgefunden.

Auf der Ansicht, sind die versteckten Felder mit der Fremdschlüssel-Adresse ids verbunden (wie ich sie hatte), sondern auch mit falschen Werten vorausgefüllt werden müssen (so sind sie nicht null), etwa so:

Dann ist die Prozedur auf dem Controller ziemlich einfach, weil MVC ansonsten alle Teile erfolgreich verarbeitet. Ich muss nur speichern und ordnen sie, Kinder auf bis:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Create(CheckoutForm checkoutForm) 
{ 
    Address PlaceOfUse = new Address(); 
    Address HomeAddy = new Address(); 
    Address MailingAddy = new Address(); 
    Customer Client = new Customer(); 

    if (ModelState.IsValid) 
    { 
     // Not currently available to the user to be filled in by them 
     checkoutForm.PlaceOfUseAddress.StateId = 1; 

     // !!! Need to be given correct value once authorization is set up. 
     checkoutForm.EnteredBy = TestAccountId; 
     checkoutForm.ModifiedBy = TestAccountId; 
     checkoutForm.EnteredDate = System.DateTime.Now; 
     checkoutForm.ModifiedDate = System.DateTime.Now; 

     PlaceOfUse = checkoutForm.PlaceOfUseAddress; 
     HomeAddy = checkoutForm.Customer.HomeAddress; 
     MailingAddy = checkoutForm.Customer.MailingAddress; 
     db.Addresses.Add(PlaceOfUse); 
     db.Addresses.Add(HomeAddy); 
     db.Addresses.Add(MailingAddy); 
     db.SaveChanges(); 
     checkoutForm.PlaceOfUseAddressId = PlaceOfUse.AddressId; 
     checkoutForm.Customer.HomeAddressId = HomeAddy.AddressId; 
     checkoutForm.Customer.MailingAddressId = MailingAddy.AddressId; 

     Client = checkoutForm.Customer; 
     db.Customers.Add(Client); 
     db.SaveChanges(); 
     checkoutForm.CustomerId = Client.CustomerId; 
     db.CheckoutForms.Add(checkoutForm); 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    else { 
     // To review in debug mode, when there are problems 
     //var errors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors); 

     ViewBag.HomeStateList = new SelectList(db.RT_STATE_LIST, "ST_SEQ", "ST_ABBR", checkoutForm.Customer.HomeAddress.StateId); 
     ViewBag.MailingStateList = new SelectList(db.RT_STATE_LIST, "ST_SEQ", "ST_ABBR", checkoutForm.Customer.MailingAddress.StateId); 
     return View(checkoutForm); 
    } 
} 

Plus von Erstellen Sie die „Bind“ Attribut zu entfernen() 's Parameter machte es alles viel einfacher.

+0

Ich möchte auch kommentieren, dass das folgende ausgezeichnete, verwandte Informationen zur Aktualisierung dieser Art von komplexen Objektbeziehungen in Bearbeiten hat: http://stackoverflow.com/questions/15336248/entity-framework-5-updating-a- Aufzeichnung – GG2

Verwandte Themen