【问题标题】: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 应用程序中使用 LINQ 无法在多对多关系中获得预期结果
【发布时间】:2018-09-01 11:40:58
【问题描述】:

我正在尝试使用 Asp.net C#、MVC、Codefirst 方法开发应用程序。

我有两个类,分别是 Actors 和 Movies,它们之间有多对多的关系。 (一个演员可以有很多电影,一部电影可以有很多演员)

现在我遇到了一个问题,我可以从两个表中检索数据,但不如预期的那样,我认为我的代码逻辑的某个地方出了点问题。

例如,我可以从数据库中检索电影列表,当我单击每部电影时,它会将我重定向到属于该特定电影的页面,这在这一点上是有意义的,但现在我想检索列表在这部电影中扮演角色的演员,我失败了。 (我可以检索数据库中存在的完整演员列表,但不能检索在特定电影中扮演角色的特定演员)。

这些是我的模型:

这是 Actor 类:

public class Actors
{
    public int Id { get; set; }
    public string actor_name { get; set; }
    public string country_of_birth { get; set; }    
}

这是电影类:

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

这是一个显示电影列表的索引视图,并有一个链接可以单独查看每部电影的详细信息:

@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 逻辑有问题。

如果有这方面的专业知识的人正在阅读这篇文章,请指导我使用我应该用于 LINQ 的正确逻辑或任何其他有助于我获得结果的方法。

【问题讨论】:

  • 您必须将两个模型的关系设置为pkfk

标签: c# sql-server asp.net-mvc linq ef-code-first


【解决方案1】:

1) 您必须在模型ActorsMovies 之间配置多对多关系

您将按照步骤发送至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; }
}

你的上下文类会是这样的

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

尝试一次可能对你有帮助:)

【讨论】:

  • @Prince Walizada,查看答案可能对您有帮助:)
  • 非常感谢,你很有帮助。但现在数据录入阶段出现了新情况。我无法访问通过 fluent API 自动生成的中间表(MoviesActors 表)。我想访问该表并通过包含数据输入表单的视图插入一些数据。让我在数据输入视图的顶部更具体一点,我不能引用这个中间表:例如,在数据输入视图的顶部,我应该能够设置这样的引用:@model Myproject.Models.MoviesActors 但MoviesActors 没有出现,所以我可以参考它。
  • 我还发布了一个关于这方面的新问题,可以通过以下链接为您提供更多详细信息:stackoverflow.com/questions/52129988/…
猜你喜欢
  • 2017-07-02
  • 2011-01-09
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 2013-07-16
  • 1970-01-01
相关资源
最近更新 更多