2017-11-19 4 views
0

Ich versuche, eine einfache Anwendung zu erstellen, aber meine Ansicht gibt nichts zurück, wenn ich versuche, ein Viewmodel zu verwenden. Ich nehme an, die "db. [TableName] .ToList();", die funktioniert, wenn sie auf ein Domänenmodell angewendet wird, ist nicht genug und die Auswahl sollte auf andere Weise geschehen, wenn ich ein Viewmodel verwende, aber ich habe keine Idee es. Bitte helfen Sie. Vielen Dank.ASP.NET MVC Viewmodel gibt nichts zurück

Town.cs

using System.Collections.Generic; 

namespace City.Models 
{ 
    public class Town 
    { 
     public Town() 
     { 
      Streets = new List<Street>(); 
     } 
     public int TownId { get; set; } 
     public string TownName { get; set; } 
     public virtual ICollection<Street> Streets { get; set; } 
    } 
} 

Street.cs

using System.Collections.Generic; 

namespace City.Models 
{ 
    public class Street 
    { 
     public Street() 
     { 
      Houses = new List<House>(); 
     } 
     public int StreetId { get; set; } 
     public string StreetName { get; set; } 
     public virtual ICollection<House> Houses { get; set; } 
    } 
} 

House.cs

namespace City.Models 
{ 
    public class House 
    { 
     public int HouseId { get; set; } 
     public string HoueseName { get; set; } 
     public int StreetId { get; set; } 
     public virtual Street Street { get; set; } 
    } 
} 

Boden CS-

namespace City.Models 
{ 
    public class Floor 
    { 
     public int FloorId { get; set; } 
     public int FloorNumber { get; set; } 
     public int FireExtinguisherId { get; set; } 
    } 
} 

FireExtinguisher.cs

namespace City.Models 
{ 
    public class FireExtinguisher 
    { 
     public int FireExtinguisherId { get; set; } 
     public string FireExtinguisherName { get; set; } 
     public int FloorId { get; set; } 
    } 
} 

MyViewModel.cs

namespace City.Models 
{ 
    public class MyViewModel 
    { 
     public MyViewModel() 
     { 
      Town = new Town(); 
      Street = new Street(); 
      House = new House(); 
      Floor = new Floor(); 
      FireExtinguisher = new FireExtinguisher(); 
     } 

     public int MyViewModelId { get; set; } 
     public Town Town { get; set; } 
     public Street Street { get; set; } 
     public House House { get; set; } 
     public Floor Floor { get; set; } 
     public FireExtinguisher FireExtinguisher { get; set; } 
    } 
} 

ApplicationDbContext.cs

HomeController.cs (ich denke, das Problem liegt hier)

using System.Linq; 
using System.Web.Mvc; 
using City.Models; 

namespace City.Controllers 
{ 
    public class HomeController : Controller 
    { 
     private ApplicationDbContext db; 
     public HomeController() 
     { 
      db = new ApplicationDbContext(); 
     } 
     public ActionResult Index() 
     { 
      return View(db.MyViewModels.ToList()); 
     } 

     public ActionResult About() 
     { 
      ViewBag.Message = "Your application description page."; 

      return View(); 
     } 

     public ActionResult Contact() 
     { 
      ViewBag.Message = "Your contact page."; 

      return View(); 
     } 
    } 
} 

Index.cshtml

@model IEnumerable<City.Models.MyViewModel> 

<h2>Map information</h2> 

<div class="container"> 
    <table class="table"> 
     <thead> 
      <tr> 
       <th>Town</th> 
       <th>Street</th> 
       <th>House</th> 
       <th>Floor</th> 
       <th>FireExtinguisher</th> 
      </tr> 
     </thead> 
     @foreach (var item in Model) 
     { 
      <tbody> 
       <tr> 
        <td>@(item.Town.TownName)</td> 
        <td>@(item.Street.StreetName)</td> 
        <td>@(item.House.HoueseName)</td> 
        <td>@(item.Floor.FloorNumber)</td> 
        <td>@(item.FireExtinguisher.FireExtinguisherName)</td> 
       </tr> 
      </tbody> 
     } 
    </table> 
</div> 

Auch wenn ich Testdaten in der db haben, das ist alles was ich sehe, wenn ich es laufe:

Image is here

Bitte sagen Sie mir, was ich beheben sollte, wie Daten abgerufen werden.

Dank

EDIT @CrowdCoder

new picture here

+0

Ich glaube nicht, dass Sie die richtigen Konventionen für Entity Framework verwenden. Sie erweitern alles im Konstruktor von 'MyViewModel' und ich glaube nicht, dass Ihre Struktur die richtigen Navigationseigenschaften erzeugt. Es ist jedoch eine Weile her, seit ich EF benutzt habe. In Ihrem Controller trennen Sie diese Zeile in eine Variable, so dass Sie daran knacken können und schauen Sie auf ihren Wert 'db.MyViewModels.ToList()' (auch sollten Sie nicht ToList() this) – Crowcoder

+0

Ich habe versucht, aber es brach ohne ToList(). meinen Beitrag bearbeitet, siehe Änderungen – Riwi

+0

Sie können helfen, Ihr Problem als EF-bezogen zu diagnostizieren oder nicht, indem Sie ein fest codiertes Ansichtsmodell in Ihrem Controller zurückgeben, anstatt in die Datenbank zu rufen. Zum Testen erstellen Sie manuell einige MyView-Modelle und sehen Sie, ob Ihre Ansicht diese anzeigt. – Crowcoder

Antwort

1

Ich denke, Ihr Verständnis über View-Modell falsch ist.

View-Modell ist eine Klasse, um Daten zwischen Ihrer Ansicht und Ihrer Aktionsmethode zu übertragen. Ansicht Modell ist spezifisch für die Ansicht. Wenn Ihre Ansicht nur zwei Eigenschaften anzeigen muss (Name und Age), hat Ihr Ansichtsmodell nur diese beiden Eigenschaften. Sie müssen nicht alle Eigenschaften aus Ihrem Entitätsmodell in die Ansichtsmodellklasse übernehmen.

Ich sehe, dass Sie eine neue Kollektion auf den Ihre db Zusammenhang macht Dies gilt

public DbSet<MyViewModel> MyViewModels { get; set; } 

keinen Sinn gegeben. Wie ich bereits erwähnt habe, sind View-Modelle UI-Probleme. Es sollte nicht in Ihrem Datenzugriffscode enthalten sein. Mischen Sie auch nicht die Entitäten, die von Ihrer ORM-Ebene in Ihrem Ansichtsmodell erstellt wurden.

Auch Ansicht Modelle sind einfache POCOs. Es sollte Lean-Flat-Klassen mit Eigenschaften sein. Es liegt in Ihrer Verantwortung, die Eigenschaftswerte zu laden. Sie können dies in Ihrer Aktionsmethode oder einer anderen von Ihrer Aktionsmethode aufgerufenen Methode tun.

Angenommen, Sie haben eine Liste von Häusern angezeigt werden sollen mit ihrem Straßenname ist, haben Sie einen Blick Modell wie diese

public class HouseViewModel 
{ 
    public int HouseId { set; get;} 
    public string HoueseName { set;get;} 
    public string StreetName { set;get; } 
} 

Jetzt in Ihrer Ansicht erstellen, geben Sie einfach diese Eigenschaften zugreifen

@model IEnumerable<HouseViewModel> 
<table> 
@foreach(var item in Model) 
{ 
    <tr> 
     <td>@item.HouseId </td> 
     <td>@item.HoueseName </td> 
     <td>@item.StreetName </td> 
    </tr> 
} 
</table> 

Damit dieser Code funktioniert, müssen Sie natürlich sicherstellen, dass Sie eine Liste von HouseViewModel erstellen und sie von Ihrer Aktionsmethode an die Ansicht senden.

public ActionResult Index() 
{ 
    var list= new List<HouseViewModel>{ 
       new HouseViewModel { HouseId =1,HoueseName ="Abc", StreetName ="Detroit"}, 
       new HouseViewModel { HouseId =2,HoueseName ="Xyz", StreetName ="Novi"} 
    }; 
    return View(list); 
} 

Jetzt können Sie sehen, dass, wie wir sind View-Modell unter Verwendung von Daten aus der Aktionsmethode zur Ansicht zu übertragen. Hier haben wir nur die Eigenschaftswerte für die Elemente in der Liste, die wir senden, hart codiert. Wir können das aktualisieren, um aus Ihrem EF db-Kontext nach Bedarf zu lesen.

Lassen Sie uns alle Häuser lesen, verwenden Sie die LINQ-Projektion, um ein Objekt für jedes Objekt in dieser Sammlung zu erstellen, und weisen Sie die Eigenschaftswerte zu.

public ActionResult Index() 
{ 
    var houses = db.Houses 
        .Select(a=>new HouseViewModel 
            { HouseId =a.HouseId, 
            HoueseName =a.HouseName, 
            StreetName = a.Street.StreetName 
            }) 
        .ToList(); 
    return View(houses); 
} 
+0

Während es schlechtes Design sein könnte, gibt es kein Gesetz gegen die Verwendung der gleichen Klassen in Ihrem Kontext als in Ihrem Ansichtsmodell, so dass das gemeldete Problem nicht verursacht wird. Beachten Sie außerdem, dass die Eigenschaften des Modells andere Typen sind, keine Zeichenfolgen. Daher müssen Navigationseigenschaften verknüpft werden. – Crowcoder

+0

"Wir können das aktualisieren, um aus Ihrem EF db-Kontext nach Bedarf zu lesen." - Ja, das ist eigentlich der springende Punkt meiner Frage. Wie ich bereits oben darauf hingewiesen habe, ist HC-ing-Werte eine funktionierende Lösung, aber offensichtlich ist es nicht das, was ich will, sondern sie von db zu holen. Was deine Empfehlung für die VM-Änderungen betrifft, danke ich, ich werde tun, wie empfohlen.Wie kann ich also VM-Eigenschaften den Eigenschaften eines Domänenmodells zuordnen, wenn VM keine DB-Entität ist? Wie kann ich Daten aus der Datenbank abrufen? – Riwi

+0

Ich habe gerade den Code aktualisiert, um Ihnen zu zeigen, wie Sie aus Ihrem DB-Kontext lesen und den View-Modell-Objekten zuordnen können. Werfen Sie einen Blick auf die aktualisierte Antwort. – Shyju