创建一个包含 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。
我是 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。