如何让 ViewBag 显示 class' 属性?
How do I make ViewBag display class' property?
我有两个模型(忍者和道场)。
他们是一对多的关系(忍者属于一个道场,而道场可以有多个忍者)。
我正在使用 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;}
}
}
忍者工厂:
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 但它没有打印出@ninja.Dojo.Name 说
RuntimeBinderException: 无法对空引用执行运行时绑定
如何使用 ViewBag 显示属于 Ninja class 的道场 class 的属性??
在此先感谢您。
根据 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;});
这段代码有几个问题。道场未加载,您不处理浪人(ninjas/samurais 没有 Dojos/masters)。
正如@peinearydevelopment 所解释的那样,Dapper 不会像 full-featured ORM 那样自动加载相关 objects。您必须在一行中同时 return 和 objects,例如使用 JOIN 并使用 multi-mapping 将不同的字段映射到不同的 objects。
你可以这样写:
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;
});
更好的选择是创建一个 View,returns Ninjas with 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";
在这种情况下,您必须更改 MVC 视图循环以忽略空值。您可以检查 Dojo 并完全删除 header,或者呈现不同的片段:
@foreach(var ninja in Model.Ninja)
{
<h2>@ninja.Name</h2>
@if (ninja.Dojo != null)
{
<h4>@(ninja?.Dojo?.Name)??"Ronin!"</h4>
}
}
请注意,我使用 Model
而不是 ViewBag
。编写和调试强类型视图要容易得多。您可以直接从您的控制器 return 忍者 :
//Controller
var ninjas= ninjaFactory.FindAll();
return View(ninjas);
//View
@model IEnumerable<Ninja>
@foreach(var ninja in Model)
或者作为 ViewModel 的一部分 class :
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)
我有两个模型(忍者和道场)。
他们是一对多的关系(忍者属于一个道场,而道场可以有多个忍者)。
我正在使用 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;}
}
}
忍者工厂:
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 但它没有打印出@ninja.Dojo.Name 说
RuntimeBinderException: 无法对空引用执行运行时绑定
如何使用 ViewBag 显示属于 Ninja class 的道场 class 的属性??
在此先感谢您。
根据 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;});
这段代码有几个问题。道场未加载,您不处理浪人(ninjas/samurais 没有 Dojos/masters)。
正如@peinearydevelopment 所解释的那样,Dapper 不会像 full-featured ORM 那样自动加载相关 objects。您必须在一行中同时 return 和 objects,例如使用 JOIN 并使用 multi-mapping 将不同的字段映射到不同的 objects。
你可以这样写:
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;
});
更好的选择是创建一个 View,returns Ninjas with 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";
在这种情况下,您必须更改 MVC 视图循环以忽略空值。您可以检查 Dojo 并完全删除 header,或者呈现不同的片段:
@foreach(var ninja in Model.Ninja)
{
<h2>@ninja.Name</h2>
@if (ninja.Dojo != null)
{
<h4>@(ninja?.Dojo?.Name)??"Ronin!"</h4>
}
}
请注意,我使用 Model
而不是 ViewBag
。编写和调试强类型视图要容易得多。您可以直接从您的控制器 return 忍者 :
//Controller
var ninjas= ninjaFactory.FindAll();
return View(ninjas);
//View
@model IEnumerable<Ninja>
@foreach(var ninja in Model)
或者作为 ViewModel 的一部分 class :
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)