2017-11-19 21 views
0

単純なアプリケーションを作成しようとしましたが、ビューモデルを使用しようとしたときに何も表示されません。私は、ドメインモデルに適用されたときに動作する "db。[TableName] .ToList();"は十分ではなく、ビューモデルを使用するときに選択が異なる方法で行われるべきだと思っていますが、それ。助けてください。ありがとうございました。ASP.NET MVC Viewmodelから何も返されません。

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; } 
    } 
} 

フロア.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

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
    { 
     public DbSet<Town> Towns { get; set; } 
     public DbSet<Street> Streets { get; set; } 
     public DbSet<House> Houses { get; set; } 
     public DbSet<Floor> Floors { get; set; } 
     public DbSet<FireExtinguisher> FireExtinguishers { get; set; } 
     public DbSet<MyViewModel> MyViewModels { get; set; } 
     public ApplicationDbContext() 
      : base("DefaultConnection", throwIfV1Schema: false) 
     { 
     } 

     public static ApplicationDbContext Create() 
     { 
      return new ApplicationDbContext(); 
     } 
    } 

HomeController.cs(私は問題がここにあると思います)

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> 

私はデシベルのテストデータを持っているにもかかわらず、これがすべてであります

Image is here

データを取得する方法を教えてください。おかげ

EDIT @CrowdCoder

new picture here

+0

私はあなたがEntity Frameworkに対して適切な規則を使用しているとは思わないでしょう。あなたは 'MyViewModel'のコンストラクタですべてを新しくしていますが、あなたの構造が正しいナビゲーションプロパティを作成するとは思いません。しかし、私はEFを使ってからしばらくしています。あなたのコントローラでは、この行を変数に区切って、値を 'db.MyViewModels.ToList()'で見ることができます(これはToList()にする必要はありません) – Crowcoder

+0

私は試みましたが、ToListなしで壊れました()。私のポストを編集してください。 – Riwi

+0

あなたはデータベースに電話するのではなく、コントローラにハードコードされたビューモデルを返すことで、EF関連の問題を診断するのに役立ちます。テストのために、いくつかのMyViewModelを手動で作成し、ビューに表示されるかどうかを確認してください。 – Crowcoder

答えて

1

私はビューモデルについてのご理解が間違っていると思います。

ビューモデルは、ビューとアクションメソッドの間でデータを転送するクラスです。 ビューモデルはビューに固有です。したがって、ビューで2つのプロパティ(NameおよびAge)のみを表示する必要がある場合、ビューモデルには2つのプロパティのみが表示されます。あなたのエンティティモデルからすべてのプロパティをビューモデルクラスに持っていく必要はありません。

私はあなたがあなたのデシベルコンテキストに新しいコレクションを追加したことがわかり、

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

これは、任意の理にかなっていません。前述のように、ビューモデルはUIの問題です。それはあなたのデータアクセスコードにあってはなりません。 ORMレイヤーで作成したエンティティをビューモデルに混在させないでください。

また、ビューモデルは単純なPOCOです。これは、プロパティを持つフラットなクラスでなければなりません。プロパティ値をロードするのはあなたの責任です。あなたはあなたのアクションメソッドまたはあなたのアクションメソッドから呼び出される別のメソッドでそれを行うことができます。

、あなたのビューで今、この

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

などのビューモデルを作成します、あなたは、単にこれらのプロパティ

@model IEnumerable<HouseViewModel> 
<table> 
@foreach(var item in Model) 
{ 
    <tr> 
     <td>@item.HouseId </td> 
     <td>@item.HoueseName </td> 
     <td>@item.StreetName </td> 
    </tr> 
} 
</table> 
にアクセスすることは通りの名前だと、あなたが家のリストを表示したいとしましょう

もちろん、このコードを動作させるには、HouseViewModelのリストを作成し、アクションメソッドからビューに送信する必要があります。

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); 
} 

今、あなたはどのように我々はビューにアクションメソッドからデータを転送するためにビューモデルを使用していることがわかります。ここでは、送信するリスト内の項目のプロパティ値をハードコードしました。必要に応じてEF DBコンテキストから読み込むように更新できます。

すべての家を読んで、LINQ投影を使用して、そのコレクションの各アイテムにHouseViewModelオブジェクトを作成し、プロパティ値を割り当てます。

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

デザインが悪いかもしれませんが、報告された問題を引き起こしていないように、あなたのビューモデルと同じクラスを使用することに対する法律はありません。また、モデルのプロパティが文字列ではなく他のタイプであることに注意してください。ナビゲーションプロパティを配線する必要があります。 – Crowcoder

+0

"必要に応じてEF DBコンテキストから読み込むように更新できます。" - はい、これは実際に私の質問の全ポイントです。上ですでに指摘したように、hc-ing値は実用的な解決策ですが、明らかにこれは私が望むものではなく、dbから取り出すことです。 VMの変更についてのあなたのお勧めについては、ありがとうございます、私はアドバイスします。VMがDBエンティティでない場合、どうすればVMプロパティをドメインモデルのプロパティに関連付けることができますか? DBからどのようにデータを取り戻すことができますか? – Riwi

+0

dbコンテキストから読み込み、ビューモデルオブジェクトにマップする方法を示すコードを更新しました。更新された答えを見てください。 – Shyju

関連する問題