创建一个包含 3 个表的列的视图

Create a view that contains columns from 3 tables

我是 Visual Studio 的新手,我需要你的帮助。

我正在使用 .NET Core 3.1、C#、MVC 和 Identity,我正在尝试创建一个包含来自 3 个表的列的视图。

预期的结果是这样的:

Personal info
Last name: xxx
First name: xxx

Skills
Skill ID: 1   Skill: xxx
Skill ID: 2   Skill: xxx
Skill ID: 3   Skill: xxx

Jobs
Job ID: 1   Employee: xxx   Subject: xxx
Job ID: 2   Employee: xxx   Subject: xxx

怎么办才会有以上的看法?

我拥有的3个模型是:

public class ApplicationUser : IdentityUser
{
   public string StuLna { get; set; } // Last name
   public string StuFna { get; set; } // First name   
   …
   public virtual ICollection<TblSkill> TblSkills { get; set; }
   public virtual ICollection<TblJobHistory> TblJobHistories { get; set; }
}

public class TblSkill
{
   [Key]
   public int    SkiIde { get; set; } // Skill ID
   public string SkiSki { get; set; } // Skill
   …
   [ForeignKey("ApplicationUser")]
   public string  AppUserId { get; set; } // ApplicationUser Id
   public virtual ApplicationUser ApplicationUser { get; set; }
}

public class TblJobHistory
{
   [Key]
   public int    JobIde { get; set; } // Job ID
   public string JobEmp { get; set; } // Employee
   public string JobSub { get; set; } // Subject
   …
   [ForeignKey("ApplicationUser")]
   public string  AppUserId { get; set; } // ApplicationUser Id
   public virtual ApplicationUser ApplicationUser { get; set; }
}

DbContext:

public class AppDBContext : IdentityDbContext<ApplicationUser, IdentityRole, string>
{
   public AppDBContext(DbContextOptions<AppDBContext> options)
   : base(options) 
   { 
   }

   public virtual DbSet<TblSkill> TblSkills { get; set; }
   public virtual DbSet<TblJobHistory> TblJobHistories { get; set; }

   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
      base.OnModelCreating(modelBuilder);

      modelBuilder.Entity<TblSkill>()
         .HasOne(a => a.ApplicationUser)
         .WithMany(s => s.TblSkills)
        .HasForeignKey(a => a.AppUserId);

      modelBuilder.Entity<TblJobHistory>()
         .HasOne(a => a.ApplicationUser)
         .WithMany(j => j.TblJobHistories)
        .HasForeignKey(a => a.AppUserId);

      public DbSet<MyApp.ViewModels.PersonalInfoVM> PersonalInfoVM { get; set; }
}

到目前为止我已经创建了这些:

查看模型:

public class PersonalInfoVM
{
   [Key]
   public string  AppUserId { get; set; } // ApplicationUser Id
   public virtual ApplicationUser ApplicationUsers { get; set; }
   public virtual TblSkill TblSkills { get; set; }
   public virtual TblJobHistory TblJobHistories { get; set; }
}

控制器:

public IActionResult PersonalInfoPreview()
{
   var userid = _userManager.GetUserId(HttpContext.User);
      
   List<ApplicationUser> users = _context.Users.ToList();
   List<TblSkill> skills = _context.TblSkills.ToList();
   List<TblJobHistory> jobHistories = _context.TblJobHistories.ToList();
         
   var model = from u in users

   join s in skills on u.Id equals s.AppUserId into table1
      from s in table1.ToList()
      join j in jobHistories on u.Id equals j.AppUserId into table2
      from j in table2.ToList()
      select new PersonalInfoVM
         {
            ApplicationUsers = u,
            TblSkills = s,
            TblJobHistories = j
         };

   return View(model);
}

查看页面:

@model IEnumerable<MyApp.ViewModels.PersonalInfoVM >
@{ViewData["Title"] = "PersonalInfoPreview";}

<table class="table">
    <thead>
        <tr>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.ApplicationUsers.StuLna</td>
            </tr>
        }

        @foreach (var item in Model)
        {
            <tr>
                <td>@item.TblSkills.SkiSki</td>
            </tr>
        }

        @foreach (var item in Model)
        {
            <tr>
                <td>@item.TblJobHistories.HisSta</td>
            </tr>
        }

    </tbody>
</table>

这是当前用户拥有 2 项技能和 2 份工作的结果:

Papadopoulos
Papadopoulos
Papadopoulos
Papadopoulos
user1-skill1
user1-skill1
user1-skill2
user1-skill2
user1-employee1
user1-employee2
user1-employee1
user1-employee2

您的代码应用程序中有几个问题超出了您的问题范围。

首先要做的就是改变你查看模型:

public class ViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public List<Skills> Skills { get; set; }
    public List<Jobs> Jobs { get; set; }

}

您的 Controller 代码可以替换为:

var model = _context.Users.Where(x => xAppUserId == userid).Include(x => x.TblSkills).Include(x => x.TblJobHistories).Select(x => new ViewModel()
{
    FirstName = x.FirstName,
    LastName = x.LatNsme,
    Skills = x.TblSkills.ToList(),
    Jobs = x.TblJobHistories.ToList()
}).FirstOrDefault();

return View(model);

这应该输出结果作为问题开头的示例。在您看来,您似乎想要 return 所有用户,然后您只需删除 where 子句并将 FirstOrDefault 更改为 ToList()

请注意,您的视图必须反映更新的 ViewModel

我会将您的 ViewModel 设置如下:

public class PersonalInfoVM
{
   public string  AppUserId { get; set; } // ApplicationUser Id
   public ApplicationUser ApplicationUser { get; set; }
   public IEnumerable<TblSkill> TblSkills { get; set; }
   public IEnumerable<TblJobHistory> TblJobHistories { get; set; }
}

并像这样加载它:

public IActionResult PersonalInfoPreview()
{
   var vm = new PersonalInfoVM();
   vm.AppUserId = _userManager.GetUserId(HttpContext.User);
   vm.ApplicationUser = _userManager.FindByName(User.Identity.Name);
   vm.TblSkills = _context.TblSkills.Where(x=>x.AppUserId == vm.AppUserId).ToList();
   vm.TblJobHistories = _context.TblJobHistories.Where(x=>x.AppUserId == vm.AppUserId).ToList();
   return View(vm);
}

最后显示如下:

@model  MyApp.ViewModels.PersonalInfoVM;
@{ViewData["Title"] = "PersonalInfoPreview";}

<table class="table">
    <tbody> 
            <tr>
                <td colspan="3">Personal info</td>
            </tr>
            <tr>
                <td colspan="2">First name</td>
                <td>@Model.ApplicationUser.FirstName</td>
            </tr>
         
            <tr>
                <td colspan="2">Last name</td>
                <td>@Model.ApplicationUser.LastName</td>
            </tr>
         

        @foreach (var item in Model.TblSkills)
        {
            <tr>
                <td colspan="2">@item.SkiIde</td>
                <td>@item.SkiSki</td>
            </tr>
        } 
        @foreach (var item in Model.TblJobHistories )
        {
            <tr>
                <td>@item.JobIde </td>
                <td>@item.JobEmp </td>
                <td>@item.JobSub </td>
            </tr>
        }

    </tbody>
</table>

根据你的代码,我想你是想查询具体的用户信息,获取相关的Skills和JobHistories。如果是这样的话,因为您已经为这些 table 配置了一对多关系,我认为您可以使用 Include 方法来查找相关实体。请参考以下示例代码:

数据库上下文:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Projects> Projects { get; set; }
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
        
    }

    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<TestTable> TestTables { get; set; }



    public virtual DbSet<TblSkill> TblSkills { get; set; }
    public virtual DbSet<TblJobHistory> TblJobHistories { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Blog>()
            .HasMany(b => b.Posts)
            .WithOne();
    }
}

控制器中的代码:

    public IActionResult Details()
    {
        //query the application user table and find the related entities.
        var result = _context.Users
            .Include(c=>c.TblSkills)
            .Include(c=>c.TblJobHistories)
            .Where(c => c.UserName == "Dillion")
            .Select(c=> new PersonalInfoVM() { AppUserId = c.Id, ApplicationUsers = c }).FirstOrDefault();
        return View(result);
    }

查看模型:

public class PersonalInfoVM
{
    [Key]
    public string AppUserId { get; set; } // ApplicationUser Id
    public virtual ApplicationUser ApplicationUsers { get; set; }
}

查看页面中的代码:

@model EFCore.Models.PersonalInfoVM

@{
    ViewData["Title"] = "Details";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Details</h1>

<div>
    <h4>PersonalInfoVM</h4>
    <hr />
    <div>
        <dl class="row">
            <dt class="col-sm-2">
                @Html.DisplayNameFor(model => model.AppUserId)
            </dt>
            <dd class="col-sm-10">
                @Html.DisplayFor(model => model.AppUserId)
            </dd>
        </dl>
        <dl class="row">
            <dt class="col-sm-2">
                @Html.DisplayNameFor(model => model.ApplicationUsers.UserName)
            </dt>
            <dd class="col-sm-10">
                @Html.DisplayFor(model => model.ApplicationUsers.UserName)
            </dd>
        </dl>
        @foreach (var item in Model.ApplicationUsers.TblSkills)
        {
            <dl class="row">
                <dt class="col-sm-2">
                    SkiSki
                </dt>
                <dd class="col-sm-10">
                    @item.SkiSki
                </dd>
            </dl>
        }
        @foreach (var item in Model.ApplicationUsers.TblJobHistories)
        {
            <dl class="row">
                <dt class="col-sm-2">
                    Employee:
                </dt>
                <dd class="col-sm-10">
                    @item.JobEmp
                </dd>
            </dl>
            <dl class="row">
                <dt class="col-sm-2">
                    Subject:
                </dt>
                <dd class="col-sm-10">
                    @item.JobSub
                </dd>
            </dl>
        }
    </div>
</div>
<div>
    @Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
    <a asp-action="Index">Back to List</a>
</div>

结果是这样的:

更多阅读相关资料的详细信息,您可以查看this document