2017-09-09 1 views
1

두 개의 모델 (Ninja & Dojo)이 있습니다.ViewBag 디스플레이 클래스 '속성을 만들려면 어떻게해야합니까?

일대 다 관계 (닌자는 하나의 도장에 속하며 Dojo에는 많은 닌자가있을 수 있음)입니다.

Dapper를 사용하고 있습니다.

Ninja.cs

using System.ComponentModel.DataAnnotations; 
using dojoleague.Models; 
using System; 

namespace dojoleague.Models { 
public class Ninja : BaseEntity{ 

    [Key] 
    public long Id {get; set;} 

    [Required(ErrorMessage="You need a name!")] 
    public string Name {get; set;} 

    [Range(1,11, ErrorMessage="Must be between 1 and 10")] 
    public int Level {get; set;} 

    [Required] 
    public Dojo Dojo {get; set;} 

    public string Description {get; set;} 


    } 
} 

Ninjafactory :

public IEnumerable<Ninja> FindAll() 
{ 
    using (IDbConnection dbConnection = Connection) 
    { 
     dbConnection.Open(); 
     return dbConnection.Query<Ninja>("SELECT * FROM ninjas"); 
    } 
} 

Dojo.cs 내 컨트롤러에서

using System.ComponentModel.DataAnnotations; 
using System; 
using System.Collections.Generic; 

namespace dojoleague.Models { 
public class Dojo : BaseEntity{ 

    [Key] 
    public long Id {get; set;} 

    [Required] 
    public string Name {get; set;} 

    [Required(ErrorMessage="We have to know where it is")] 
    public string Location {get; set;} 

    [Required(ErrorMessage="Provide additional info on the Dojo")] 
    public string Description {get; set;} 

    public ICollection<Ninja> Ninjas { get; set; } 

} 
} 

,

내가 가진 :

ninjaFactory.Add(newNinja, dojo); 
System.Console.WriteLine(newNinja.Dojo.Name); 
ViewBag.Ninja = ninjaFactory.FindAll(); 
return View(); 

이제 System.Console.WriteLine (newNinja.Dojo.Name)은 콘솔에서 Dojo의 이름을 올바르게 인쇄합니다.

그러나 웹 브라우저에는 Dojo의 이름이 표시되지 않습니다. 내 cshtml에서

,

@{ 
    foreach(var ninja in ViewBag.Ninja){ 
     <h2>@ninja.Name</h2> 
     <h4>@ninja.Dojo.Name</h4> 
    } 
} 

그것은 @ ninja.Name를 인쇄 않지만이

RuntimeBinderException 말 @ ninja.Dojo.Name을 인쇄하지 않습니다 널에 런타임 바인딩을 수행 할 수 없습니다 참조

ViewBag를 사용하여 Ninja 클래스 show에 속한 Dojo 클래스의 속성을 어떻게 만들 수 있습니까 ??

미리 감사드립니다.

+0

당신이 당신의'ninjaFactory.FindAll() '방법을 쓸 수 :

//Controller var ninjas= ninjaFactory.FindAll(); return View(ninjas); //View @model IEnumerable<Ninja> @foreach(var ninja in Model) 

아니면 뷰 모델 클래스의 일환으로

? – Kahbazi

+0

공개 IEnumerable FindAll() { using (IDbConnection dbConnection = Connection) { dbConnection.Open(); return dbConnection.Query ("SELECT * FROM ninjas"); } } – Jung

+0

이것은 MVC 또는 뷰백과는 아무 관련이 없습니다. 오류 메시지는 무엇이 잘못되었는지 설명합니다. 'Dojo' 속성은 적어도 null *입니다. * 표시 할 Dojo가 있습니까? 데이터는 어떻게 생겼습니까? –

답변

1

. Dojos는로드되지 않으며 Ronins (dojos/masters없이 ninjas/samurais)를 처리하지 않습니다.

@ peinearydevelopment에서 설명한 바와 같이 Dapper는 모든 기능을 갖춘 ORM과 같이 자동으로 관련 객체를로드하지 않습니다. 하나의 행에 두 객체를 모두 반환해야합니다 (예 : JOIN). 다른 필드를 다른 객체에 매핑하려면 multi-mapping을 사용해야합니다.

당신은 쓸 수 있습니다 :

var sql ="SELECT * FROM ninjas inner join Dojos on Ninjas.DojoID=Docos.ID"; 
dbConnection.Query<Ninja, Dojo, Ninja>(sql, (ninja, dojo) => 
    { 
     ninja.Dojo = dojo; 
     return ninja; 
    }); 

더 좋은 옵션이 Dojos와 닌자를 반환하는 보기을 만들 수 있으며, 그것에지도 할 예 :

var sql ="SELECT * FROM ninjasWithDojos ..."; 
dbConnection.Query<Ninja, Dojo, Ninja>(sql, (ninja, dojo) => 
    { 
     ninja.Dojo = dojo; 
     return ninja; 
    }); 

다른 부분 문제는 닌자가 도장이 없다는 것입니다. 내부 조인을 사용하면 이러한 항목을로드 할 수도 없습니다.당신은 왼쪽 외부를 사용하여 Ronins을로드 할 수 있습니다 가입 :

var sql ="SELECT * FROM ninjas left outer join Dojos on Ninjas.DojoID=Docos.ID"; 

당신이 널 (null)을 무시하도록 MVC보기 루프를 변경해야이 경우. 당신은 도장을 확인하고 전체 헤더를 제거하거나 다른 조각 렌더링 할 수있다 : 내가 대신 ViewBagModel를 사용

@foreach(var ninja in Model.Ninja) 
{ 
    <h2>@ninja.Name</h2> 
    @if (ninja.Dojo != null) 
    {  
     <h4>@(ninja?.Dojo?.Name)??"Ronin!"</h4> 
    } 
} 

공지 사항. 강력한 형식의 뷰를 작성하고 디버깅하는 것이 훨씬 쉽습니다. 당신은 당신의 컨트롤러에서 직접 닌자를 반환 할 수 있습니다

var ninjas= ninjaFactory.FindAll(); 
var villains = ...; 
var game = new GameModel { Ninjas = ninjas, Villains = villains}; 
return View(game); 

//View 
@model GameModel 


@foreach(var ninja in Model.Ninjas) 
1

documentation에 따르면,이에 쿼리를 업데이트해야 할 것 같다 :이 코드에 문제가 몇 가지 있습니다 var sql = @"select * from #Ninjas n left join #Dojos d on d.Id = n.DojoId Order by n.Id";

return dbConnection.Query<Post, Dojo>(sql, (ninja, dojo)=> { ninja.Dojo = dojo; return ninja;});

+1

docs는 join에서 Dojos를 반환 할 필요가 있다고 말합니다. –

+0

@PanagiotisKanavos 예, 실제 SQL 쿼리를 포함하는 것을 잊었습니다. 업데이트되었습니다, 고마워요! – peinearydevelopment

관련 문제