在 Asp.net C#、MVC、Codefirst 应用程序中使用 LINQ 无法在多对多关系中获得预期结果
Can't get the expected result in many to many relationship using LINQ in Asp.net C#, MVC, Codefirst application
我正在尝试使用 Asp.net C#、MVC、Codefirst 方法开发应用程序。
我有两个 class 演员和电影,它们之间存在多对多关系。 (一个演员可以有很多部电影,一部电影可以有很多演员)
现在我遇到了一个问题,我可以从两个表中检索数据,但不是预期的那样,我相信我的代码逻辑某处出了问题。
例如,我可以从数据库中检索电影列表,当我点击每部电影时,它会将我重定向到属于该特定电影的页面,这在这一点上是有意义的,但现在我想检索在这部电影中扮演角色的演员名单,在这里我失败了。 (我可以检索存在于数据库中的完整演员列表,但不能检索在特定电影中扮演角色的特定演员)。
这些是我的模型:
这是演员 Class:
public class Actors
{
public int Id { get; set; }
public string actor_name { get; set; }
public string country_of_birth { get; set; }
}
这是电影 class:
public class Movies
{
public int Id { get; set; }
public string movie_title { get; set; }
public string genre { get; set; }
}
这是控制器:
public ActionResult Index()
{
var mv = _context.mvz;
if (mv==null)
{
return Content("Nothing found in database");
}
return View(mv);
}
public ActionResult Details(int? Id)
{
var dtl = _context.mvz.SingleOrDefault(a=> a.Id == Id);
var vm = new MoviesViewModel()
{
mvz = dtl,
};
if (vm==null)
{
return Content("Nothing Found!");
}
return View(vm);
}
这是显示电影列表的索引视图,并且有一个 link 用于单独显示每部电影的详细信息:
@model IEnumerable<ManyToMany_FinalProject.Models.Movies>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h5>List of Movies</h5>
<table class="table table-bordered table-hover table-responsive">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
</tr>
</thead>
@foreach (var movie in Model)
{
<tbody>
<tr>
<td>@movie.Id</td>
<td>@Html.ActionLink(movie.movie_title,"Details","Movies",new { Id = @movie.Id},null)</td>
</tr>
</tbody>
}
这是必须显示每部电影的详细信息的详细信息视图,特别是它必须显示在该特定电影中扮演角色的演员列表。
@model ManyToMany_FinalProject.ViewModel.MoviesViewModel
@{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h5>Details of @Model.mvz.movie_title</h5>
<table class="table table-bordered table-hover table-responsive">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Genre</th>
</tr>
</thead>
<tbody>
<tr>
<td>@Model.mvz.Id</td>
<td>@Model.mvz.movie_title</td>
<td>@Model.mvz.genre</td>
</tr>
</tbody>
<h5>Star cast of @Model.mvz.movie_title</h5>
<table class="table table-bordered table-hover table-responsive">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Country</th>
</tr>
</thead>
@foreach (var actor in Model.act)
{
<tbody>
<tr>
<td>@actor.Id</td>
<td>@actor.actor_name</td>
<td>@actor.country_of_birth</td>
</tr>
</tbody>
}
</table>
最后这是视图模型:
public class MoviesViewModel
{
public Movies mvz { get; set; }
public List<Actors> act { get; set; }
public MoviesViewModel()
{
mvz = new Movies();
act = new List<Actors>();
}
}
我知道我为检索控制器中的参与者列表而编写的 LINQ 逻辑有问题 class。
如果有这方面专业知识的人正在阅读这篇文章 post,请指导我正确的逻辑,我应该将其用于 LINQ 或任何其他有助于我获得结果的方法。
1) 您必须在模型 Actors
和 Movies
之间配置多对多关系
您将按照步骤 Configure Many-To-Many Relationship in Code First
。
配置关系后你的模型看起来像。
public class Actors
{
public Actors()
{
this.Movies = new HashSet<Movies>();
}
public int Id { get; set; }
public string actor_name { get; set; }
public string country_of_birth { get; set; }
public virtual ICollection<Movies> Movies { get; set; }
}
public class Movies
{
public Movies()
{
this.Actors = new HashSet<Actors>();
}
public int Id { get; set; }
public string movie_title { get; set; }
public string genre { get; set; }
public virtual ICollection<Actors> Actors { get; set; }
}
你的上下文 class 看起来像
public class YourDBContext : DBContext
{
public YourDBContext() : base("YourDbConnectionString")
{
}
public DbSet<Movies> Movies { get; set; }
public DbSet<Actors> Actors { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//If you face any problem that contains cascade delete then add below line.
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
base.OnModelCreating(modelBuilder);
}
}
2) 根据以下内容更改您的 MoviesViewModel
。
public class MoviesViewModel
{
public Movies mvz { get; set; }
public List<Actors> actrs { get; set; }
}
3) 然后您将通过以下操作方法获取您的电影及其演员。
public ActionResult Details(int? Id)
{
//This will return single movie with your parameter id
var mvz = _context.mvz.SingleOrDefault(a => a.Id == Id);
//This will gives you actors of above movie.
var actrs = mvz.Actors.ToList();
var vm = new MoviesViewModel()
{
mvz = mvz,
actrs = actrs
};
if (vm == null)
{
return Content("Nothing Found!");
}
//This view model return your both of movie and its actors.
//Capture both in your model and render in your view.
return View(vm);
}
试试看对你有帮助:)
我正在尝试使用 Asp.net C#、MVC、Codefirst 方法开发应用程序。
我有两个 class 演员和电影,它们之间存在多对多关系。 (一个演员可以有很多部电影,一部电影可以有很多演员)
现在我遇到了一个问题,我可以从两个表中检索数据,但不是预期的那样,我相信我的代码逻辑某处出了问题。
例如,我可以从数据库中检索电影列表,当我点击每部电影时,它会将我重定向到属于该特定电影的页面,这在这一点上是有意义的,但现在我想检索在这部电影中扮演角色的演员名单,在这里我失败了。 (我可以检索存在于数据库中的完整演员列表,但不能检索在特定电影中扮演角色的特定演员)。
这些是我的模型:
这是演员 Class:
public class Actors
{
public int Id { get; set; }
public string actor_name { get; set; }
public string country_of_birth { get; set; }
}
这是电影 class:
public class Movies
{
public int Id { get; set; }
public string movie_title { get; set; }
public string genre { get; set; }
}
这是控制器:
public ActionResult Index()
{
var mv = _context.mvz;
if (mv==null)
{
return Content("Nothing found in database");
}
return View(mv);
}
public ActionResult Details(int? Id)
{
var dtl = _context.mvz.SingleOrDefault(a=> a.Id == Id);
var vm = new MoviesViewModel()
{
mvz = dtl,
};
if (vm==null)
{
return Content("Nothing Found!");
}
return View(vm);
}
这是显示电影列表的索引视图,并且有一个 link 用于单独显示每部电影的详细信息:
@model IEnumerable<ManyToMany_FinalProject.Models.Movies>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h5>List of Movies</h5>
<table class="table table-bordered table-hover table-responsive">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
</tr>
</thead>
@foreach (var movie in Model)
{
<tbody>
<tr>
<td>@movie.Id</td>
<td>@Html.ActionLink(movie.movie_title,"Details","Movies",new { Id = @movie.Id},null)</td>
</tr>
</tbody>
}
这是必须显示每部电影的详细信息的详细信息视图,特别是它必须显示在该特定电影中扮演角色的演员列表。
@model ManyToMany_FinalProject.ViewModel.MoviesViewModel
@{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h5>Details of @Model.mvz.movie_title</h5>
<table class="table table-bordered table-hover table-responsive">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Genre</th>
</tr>
</thead>
<tbody>
<tr>
<td>@Model.mvz.Id</td>
<td>@Model.mvz.movie_title</td>
<td>@Model.mvz.genre</td>
</tr>
</tbody>
<h5>Star cast of @Model.mvz.movie_title</h5>
<table class="table table-bordered table-hover table-responsive">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Country</th>
</tr>
</thead>
@foreach (var actor in Model.act)
{
<tbody>
<tr>
<td>@actor.Id</td>
<td>@actor.actor_name</td>
<td>@actor.country_of_birth</td>
</tr>
</tbody>
}
</table>
最后这是视图模型:
public class MoviesViewModel
{
public Movies mvz { get; set; }
public List<Actors> act { get; set; }
public MoviesViewModel()
{
mvz = new Movies();
act = new List<Actors>();
}
}
我知道我为检索控制器中的参与者列表而编写的 LINQ 逻辑有问题 class。
如果有这方面专业知识的人正在阅读这篇文章 post,请指导我正确的逻辑,我应该将其用于 LINQ 或任何其他有助于我获得结果的方法。
1) 您必须在模型 Actors
和 Movies
您将按照步骤 Configure Many-To-Many Relationship in Code First
。
配置关系后你的模型看起来像。
public class Actors
{
public Actors()
{
this.Movies = new HashSet<Movies>();
}
public int Id { get; set; }
public string actor_name { get; set; }
public string country_of_birth { get; set; }
public virtual ICollection<Movies> Movies { get; set; }
}
public class Movies
{
public Movies()
{
this.Actors = new HashSet<Actors>();
}
public int Id { get; set; }
public string movie_title { get; set; }
public string genre { get; set; }
public virtual ICollection<Actors> Actors { get; set; }
}
你的上下文 class 看起来像
public class YourDBContext : DBContext
{
public YourDBContext() : base("YourDbConnectionString")
{
}
public DbSet<Movies> Movies { get; set; }
public DbSet<Actors> Actors { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//If you face any problem that contains cascade delete then add below line.
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
base.OnModelCreating(modelBuilder);
}
}
2) 根据以下内容更改您的 MoviesViewModel
。
public class MoviesViewModel
{
public Movies mvz { get; set; }
public List<Actors> actrs { get; set; }
}
3) 然后您将通过以下操作方法获取您的电影及其演员。
public ActionResult Details(int? Id)
{
//This will return single movie with your parameter id
var mvz = _context.mvz.SingleOrDefault(a => a.Id == Id);
//This will gives you actors of above movie.
var actrs = mvz.Actors.ToList();
var vm = new MoviesViewModel()
{
mvz = mvz,
actrs = actrs
};
if (vm == null)
{
return Content("Nothing Found!");
}
//This view model return your both of movie and its actors.
//Capture both in your model and render in your view.
return View(vm);
}
试试看对你有帮助:)