【问题标题】:Create a view that contains columns from 3 tables创建一个包含 3 个表中的列的视图
【发布时间】:2020-07-27 07:40:36
【问题描述】:

我是 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

【问题讨论】:

  • 能否请您也提供预期结果?您提供了很多代码 - 谢谢 - 但缺少实际问题或问题描述。
  • 我更正并将预期结果放在问题的顶部
  • 请不要使用匈牙利符号。删除 Tbl 前缀。
  • 另外,格式化和缩进您的代码,以便我们阅读。并且不要将实体类型用作视图模型
  • 谢谢戴。我格式化并缩进了代码。您能更具体地了解视图模型吗?

标签: .net-core asp.net-core-mvc asp.net-identity


【解决方案1】:

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

首先要做的是改变你View Model

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

}

控制器中的代码可以替换为:

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

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

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

【讨论】:

  • 我只需要特定用户的值
【解决方案2】:

我会将您的 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>

【讨论】:

    【解决方案3】:

    根据您的代码,我假设您要查询特定的用户信息并获取相关的 Skills 和 JobHistories。如果是这种情况,由于您已经为这些表配置了一对多关系,我认为您可以使用 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

    【讨论】:

      猜你喜欢
      • 2021-06-21
      • 1970-01-01
      • 2020-05-28
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多