Laden...

ViewModel 1:N

Erstellt von Xoar vor 2 Jahren Letzter Beitrag vor 2 Jahren 524 Views
X
Xoar Themenstarter:in
2 Beiträge seit 2022
vor 2 Jahren
ViewModel 1:N

Hallo zusammen,

ich bin absoluter Neuling im Bereich ASP.NET MVC und C#. Ich benutze VS2022 mit einem LocalDB MSSQL Server
Es gibt zwei Tabellen die 1:N verbunden sind. tblEinsatzbericht(1) und tblEinsatzmittel(N)

Ich möchte folgendes darstellen:
Ein Formular mit einen Datensatz (mehrere Felder) aus der Tabelle tblEinsatzbericht, mit einer Tabelle darunter wo alle verbundenen N Werte dargestellt werden, mit der Möglichkeit den Inhalt einzelner Tabellenfelder zu ändern.

Folgendes habe ich bisher gemacht.
Ein ViewModel erstellt, welches beide Modelle beinhaltet:


  public class EinsatzberichteMitEinsatzmitteln
    {
        public ViewEinsatzberichteMitJahresFilter Einsatzbericht { get; set; }  //eine zusammengesetzte VIEW vom SQL Server
        public List<TblImportEinsatzmittel> Einsatzmittel { get; set; } //N Seite, ist hier als List richtig?
    }

Im Controller habe ich diese so eingebunden:


 [HttpGet]
        public IActionResult Index(int ID)
        {
            EinsatzberichteMitEinsatzmitteln einsatzberichteMitEinsatzmitteln = new()
            {
                Einsatzbericht = _datenbankZugriff.ViewEinsatzberichteMitJahresFilter.SingleOrDefault(x => x.Einsatznummer == ID),
                Einsatzmittel = _datenbankZugriff.TblImportEinsatzmittel.Where(x => x.Einsatznummer == ID).ToList(),
            };

Und dann in der HTML Seite so eingebunden:


@model   BrandschutzStatistik.Models.EinsatzberichteMitEinsatzmitteln

<form asp-controller="Einsatzberichte" asp-action="SaveEinsatzbericht"> 
<div class="input-group mb-3">
     <span class="input-group-text"  id="basic-addon1">Einsatznummer</span>
     <input type="text" class="form-control" readonly placeholder="Einsatznummer" aria-describedby="basic-addon1" asp-for="Einsatzbericht.Einsatznummer">
.....
.....
<table> @*Tabelle N Seite*@
        @{
            foreach(var einsatzmittel in Model.Einsatzmittel)
            {
                <tr>
                    <td>@einsatzmittel.Einsatzmittel</td>
                    <td>@einsatzmittel.Alarm</td>
                    <td>@einsatzmittel.EinsatzMittelId</td>
                    <td><input asp-for="@einsatzmittel.DurchWa">@einsatzmittel.DurchWa</td> @*Dieses Feld soll im Formular änderbar sein und passend gespeichert werden*@
                </tr>
            }
        }
    </table>
</div>

...
<button class="btn btn-primary" type="submit">Speichern</button>

Es klappt soweit, dass ich alles darstellen kann, aber in der Tabelle der N Seite im input Feld keine Daten speichern kann.
Es wird zu meinem Controller Einsatzberichte geschickt, mit dem IActionResult SaveEinsatzbericht, dort kommen aber nur Daten aus **Einsatzbericht **an und nicht aus Einsatzmittel. Diese ist immer NULL.

Gehe ich die Sache falsch an, oder wie kann ich das hinbekommen?

Grüße und Danke 🙂

16.842 Beiträge seit 2008
vor 2 Jahren

Hi, gleiches Problem wie in diesem Thema: Listen abspeichern mit ASP
Du musst die Collection bekannt machen, ansonsten wird das nicht von HTTP unterstützt.

X
Xoar Themenstarter:in
2 Beiträge seit 2022
vor 2 Jahren

Danke für den Tipp in die richtige Richtung.

Folgendes musste ich ändern.
1.
In der HTML Seite meine **foreach **Schleife durch eine **for **Schleife ersetzen. Damit die erzeugten Steuerelemente einen eindeutigen Bezeichner bekommen, die dann übergeben werden.


                        @{ 
                            for (int i = 0; i < Model.Einsatzmittel.Count; i++)
                            {
                                <tr>
                                    <td><input asp-for="@Model.Einsatzmittel[i].Feld1"/></td>
                                    <td><input asp-for="@Model.Einsatzmittel[i].Feld2"/></td>
                                    <td><input asp-for="@Model.Einsatzmittel[i].Feld3"/></td>
                                    <td><input asp-for="@Model.Einsatzmittel[i].Feld4"/></td>
                                </tr>
                            }

                        }

2.
Dann im Controller eine **For **Schleife nutzen um die Werte der übergebenen Liste in die Datenbank zu speichern.


                var EinsatzmittelinDB = _datenbankZugriff.TblImportEinsatzmittel.Where(x => x.Einsatznummer == _einsatzbericht.Einsatzbericht.Einsatznummer).ToList();

                if (EinsatzmittelinDB != null) { 
                    for (int i = 0; i < EinsatzmittelinDB.Count; i++) 
                    { 
                        EinsatzmittelinDB[i].Feld1= _einsatzbericht.Einsatzmittel[i].Feld1;
                        EinsatzmittelinDB[i].Feld2= _einsatzbericht.Einsatzmittel[i].Feld2;
                        EinsatzmittelinDB[i].Feld3= _einsatzbericht.Einsatzmittel[i].Feld3;
                    }
                }

So funktioniert es bei mir.

16.842 Beiträge seit 2008
vor 2 Jahren

Du kannst es Dir auch "einfacher" machen und adaptieren, was hier mit BeginCollection umgesetzt wurde.
https://github.com/saad749/BeginCollectionItemCore

Gibt mehrere BeginCollection Implementierungen im Web zu finden.