使用EntityFramework Core和Enums作为字符串的ASP.NET Core Razor页面——第四部分

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mzl87/article/details/85339183

目录

介绍

背景

使用代码


添加项目和项目技能处理

介绍

这是一篇由多部分组成的文章的第四部分,演示了通过EntityFramework Core 2.1EF)将Cenum值映射到数据库表中的string值。它解决了enum与应用程序实体的一对多和多对多关系中的值映射问题。它在ASP.NET Core Razor Page应用程序的上下文中执行此操作。

EF是对象关系映射器(ORM)。在诸如此示例的应用程序中,有两个世界。一个是在C#中作为对象模型存在的对象世界。另一个是存在于关系数据库中的关系世界,如Microsoft SQL Server。这两个世界并不一致。ORM的功能,如EntityFramework,就是这两个世界之间的桥梁,并促进它们之间的数据传输。

第一部分。  设置实体框架数据上下文和初始客户Razor页面。(https://blog.csdn.net/mzl87/article/details/85269084

第二部分。  为客户提供完整的CRUD功能。(https://blog.csdn.net/mzl87/article/details/85312335

第三部分。创建ProjectProjectState实体,并在ProjectStateProjects之间实现一对多关系(https://blog.csdn.net/mzl87/article/details/85312583

在第四部分:添加Skill 实体(Skill 枚举,SkillTitle ProjectSkill)并实现Projects Skills之间的多对多关系,如下所示:

  • 添加实体SkillSkillTitleProjectSkill并配置到QuantumDbContext中。
  • 添加迁移,添加项目技能实体和更新数据库。
  • 搭建Skill相关的Razor页面,CustomerProjectSkills.cshtmlCustomerProjectSkillAssign.cshtmlCustomerProjectSkillDelete.cshtml。运行测试以确认功能。

背景

本系列中实施的示例应用程序适用于虚拟工程技术公司,量子工程技术公司。这家公司主要服务于石油,天然气和化学工业。到目前为止,我们已经讨论了对象模型的基础,并创建了许多ASP.NET Razor页面来处理客户,项目和项目状态。在最后一部分中,我们将讨论执行工作所需技能的列表。这项工作围绕Skill枚举和SkillProjects之间的多对多关系构建。可能有许多项目需要某种技能。执行Project还需要很多Skill。因此,项目和技能实体之间存在多对多关系。

在关系数据库中,通过为两个实体创建连接表来实现多对多关系,如下所示。

通过连接表实现多对多关系

https://img-blog.csdnimg.cn/20181229152909526

A和表B之间存在多对多关系。在关系数据库中,创建连接表JOIN-TABLE AB,与两个表具有一对多关系。

在先前版本的实体框架(EF)中,可以按约定配置连接表,而无需在对象模型中使用实体或类。但是,截至目前为止,Entity Framework Core尚未提供此功能。(参见  https://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration。)因此,我们需要在对象模型中创建和配置一个类来实现这一目的。以下讨论显示了如何使用相关的Razor页面来管理UI中的内容。

使用代码

工作对象模型显示在第一部分中,并在此处针对 Skills重复。

Skills的工作对象模型

https://img-blog.csdnimg.cn/20181229152909570

Skill.cs

namespace QuantumWeb.Model
{
    /// <summary>
    /// Skill Enumeration
    /// </summary>
    public enum Skill
    {
        Programmer, // Programmer
        ME,         // Mechanical Engineer
        ChE,        // Chemical Engineer
        CtrlE,      // Control Engineer
        SWE,        // Software Engineer
        SWArch,     // Software Architect
        WebDes,     // Web Designer
        DataSci,    // Data Scientist
        ProjMgr,    // Project Manager
        BusAnal,    // Business Analyst
        QA          // Quality Assurance Tester
    } // end public enum Skill

} // end namespace QuantumWeb.Model

我们提供了一个SkillTitle类,因此我们可以在UI中为枚举值提供相关的标题。

SkillTitle.cs

using System.Collections.Generic;

namespace QuantumWeb.Model
{
    /// <summary>
    /// SkillTitle Class
    /// </summary>
    public class SkillTitle
    {
        /// <summary>
        /// Skill Code
        /// </summary>
        public Skill SkillCode { get; set; }
        /// <summary>
        /// Skill Title
        /// </summary>
        public string Title { get; set; }

        #region Navigation Properties

        /// <summary>
        /// List of ProjectSkill Instances
        /// </summary>
        public List<ProjectSkill> ProjectSkills { get; set; }

        #endregion // Navigation Properties

    } // end public class SkillTitle

} // end namespace QuantumWeb.Model

此类引用类ProjectSkill,它将在数据库中配置连接的表。

ProjectSkill.cs

namespace QuantumWeb.Model
{
    /// <summary>
    /// ProjectSkill Class, a join entity
    /// </summary>
    /// <remarks>
    /// Note: The database table will have a non-unique index on ProjectId and SkillCode
    /// </remarks>
    public class ProjectSkill
    {

        /// <summary>
        /// ProjectSkill Identifier, primary key
        /// </summary>
        public int ProjectSkillId { get; set; }

        #region Navigation Properties

        /// <summary>
        /// Project Identifier
        /// </summary>
        public int ProjectId { get; set; }
        /// <summary>
        /// Project Reference
        /// </summary>
        public Project Project { get; set; }
        /// <summary>
        /// Skill Code
        /// </summary>
        public Skill SkillCode { get; set; }
        /// <summary>
        /// SkillTitle Reference
        /// </summary>
        public SkillTitle SkillTitle { get; set; }

        #endregion // Navigation Properties

    } // end public class ProjectSkill

} // end namespace QuantumWeb.Model

注意导航属性。它是对单个Project实例和单个SkillTitle实例的引用。ProjectIdSkillCode属性将映射到数据库中ProjectSkills表中的外键。另请注意,SkillTitle类具有集合属性ProjectSkillsList <ProjectSkill>),表明它可以与零个或多个ProjectSkill实例相关。我们现在必须修改Project类。

修改Project.cs

using System.Collections.Generic;

namespace QuantumWeb.Model
{
    /// <summary>
    /// Project Class
    /// </summary>
    public class Project
    {
        /// <summary>
        /// Project Identifier, primary key
        /// </summary>
        public int ProjectId { get; set; }
        /// <summary>
        /// Project Name
        /// </summary>
        public string ProjectName { get; set; }

        #region Navigation Properties

        /// <summary>
        /// Customer Identifier
        /// </summary>
        public int CustomerId { get; set; }

        /// <summary>
        /// Customer
        /// </summary>
        /// <remarks>
        /// Every Project has a Customer
        /// </remarks>
        public Customer Customer { get; set; }

        /// <summary>
        /// Project Status Code
        /// </summary>
        public ProjectState ProjectStateCode { get; set; }

        /// <summary>
        /// ProjectStateDescription Reference
        /// </summary>
        public ProjectStateDescription ProjectStateDescription { get; set; }

        /// <summary>
        /// List of ProjectSkill Instances
        /// </summary>
        public List<ProjectSkill> ProjectSkills { get; set; }

        #endregion // Navigation Properties

    } // end public class Project

} // end namespace QuantumApp.Model

这里我们添加了一个导航属性ProjectSkills  List <ProjectSkill>),它允许Project与多个ProjectSkill实例相关联。

现在我们必须在QuantumDbContext类中配置这些类以创建数据库映射。  首先,我们创建SkillTitleConfiguration类。

SkillTitleConfiguration.cs

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using QuantumWeb.Model;

namespace QuantumWeb.Data
{
    public class SkillTitleConfiguration : IEntityTypeConfiguration<SkillTitle>
    {
        public void Configure(EntityTypeBuilder<SkillTitle> builder)
        {
            builder.ToTable("SkillTitles");
            builder.HasKey(st => st.SkillCode);
            builder.Property(st => st.SkillCode)
            .HasColumnType("nvarchar(20)")
            .HasConversion(
                st => st.ToString(),
                st => (Skill)Enum.Parse(typeof(Skill), st));
            builder.Property(st => st.Title)
            .IsRequired()
            .HasColumnType("nvarchar(50)")
            .HasMaxLength(50);
        } // end public void Configure(EntityTypeBuilder<SkillTitle> builder)

    } // end public class SkillTitleConfiguration : IEntityTypeConfiguration<SkillTitle>

} // end namespace QuantumWeb.Data

这会将SkillTitle类映射到SkillTitles数据库表。它还可以在SkillTitles表中配置Skill枚举值和SkillCode字符串列值之间的转换。这类似于将ProjectState枚举值映射到第III部分中讨论的ProjectStateCode值。

我们现在可以配置ProjectSkill类到连接表ProjectSkills的映射。

ProjectSkillConfiguration.cs

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using QuantumWeb.Model;

namespace QuantumWeb.Data
{
    public class ProjectSkillConfiguration : IEntityTypeConfiguration<ProjectSkill>
    {
        public void Configure(EntityTypeBuilder<ProjectSkill> builder)
        {
            builder.ToTable("ProjectSkills");
            builder.HasKey(ps => ps.ProjectSkillId);
            builder.Property(ps => ps.ProjectSkillId)
            .HasColumnType("int");
            builder.Property(ps => ps.ProjectId)
            .HasColumnType("int");
            builder.Property(ps => ps.SkillCode)
            .HasColumnType("nvarchar(20)")
            .HasConversion(
                ps => ps.ToString(),
                ps => (Skill)Enum.Parse(typeof(Skill), ps));
            builder.HasIndex(ps => new { ps.ProjectId, ps.SkillCode })
            .IsUnique(false);
            builder.HasOne<Project>(ps => ps.Project)
                .WithMany(p => p.ProjectSkills)
                .HasForeignKey(ps => ps.ProjectId);
            builder.HasOne<SkillTitle>(ps => ps.SkillTitle)
                .WithMany(p => p.ProjectSkills)
                .HasForeignKey(ps => ps.SkillCode);
        } // end public void Configure(EntityTypeBuilder<ProjectSkill> builder)

    } // end public class ProjectSkillConfiguration : IEntityTypeConfiguration<ProjectSkill>

} // end namespace QuantumWeb.Data

我们现在修改QuantumDbContext类以反映这些更改。

修改QuantumDbContext.cs

using Microsoft.EntityFrameworkCore;
using QuantumWeb.Model;

namespace QuantumWeb.Data
{
    public class QuantumDbContext : DbContext
    {
        public QuantumDbContext (DbContextOptions<QuantumDbContext> options)
            : base(options)
        {
        } // end public QuantumDbContext (DbContextOptions<QuantumDbContext> options)

        #region DbSets

        /// <summary>
        /// Customer DbSet
        /// </summary>
        public DbSet<Customer> Customers { get; set; }

        /// <summary>
        /// Project DbSet
        /// </summary>
        public DbSet<Project> Projects { get; set; }

        /// <summary>
        /// ProjectStateDescription DbSet
        /// </summary>
        public DbSet<ProjectStateDescription> ProjectStateDescriptions { get; set; }

        /// <summary>
        /// SkillTitle DbSet
        /// </summary>
        public DbSet<SkillTitle> SkillTitles { get; set; }

        /// <summary>
        /// ProjectSkill DbSet
        /// </summary>
        public DbSet<ProjectSkill> ProjectSkills { get; set; }

        #endregion // DbSets

        /// <summary>
        /// Data Model Creation Method
        /// </summary>
        /// <param name="modelBuilder">ModelBuilder instance</param>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new CustomerConfiguration());
            modelBuilder.ApplyConfiguration(new ProjectConfiguration());
            modelBuilder.ApplyConfiguration(new ProjectStateDescriptionConfiguration());
            modelBuilder.ApplyConfiguration(new SkillTitleConfiguration());
            modelBuilder.ApplyConfiguration(new ProjectSkillConfiguration());
        } // end  protected override void OnModelCreating(ModelBuilder modelBuilder)

    } // end public class QuantumDbContext : DbContext

} // end namespace QuantumWeb.Data

这里我们定义DbSetsSkillTitlesProjectSkills,并添加SkillTitleConfigurationProjectSkillConfiguration类以便在OnModelCreating方法中进行处理。现在,我们在Package Manager控制台中创建迁移并更新数据库。

Add-Migration Add-Project-Skill-Entities

生成20181025222456_Add-Project-Skill-Entities.cs

using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;

namespace QuantumWeb.Migrations
{
    public partial class AddProjectSkillEntities : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "SkillTitles",
                columns: table => new
                {
                    SkillCode = table.Column<string>(type: "nvarchar(20)", nullable: false),
                    Title = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_SkillTitles", x => x.SkillCode);
                });

            migrationBuilder.CreateTable(
                name: "ProjectSkills",
                columns: table => new
                {
                    ProjectSkillId = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy",
                            SqlServerValueGenerationStrategy.IdentityColumn),
                    ProjectId = table.Column<int>(type: "int", nullable: false),
                    SkillCode = table.Column<string>(type: "nvarchar(20)", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_ProjectSkills", x => x.ProjectSkillId);
                    table.ForeignKey(
                        name: "FK_ProjectSkills_Projects_ProjectId",
                        column: x => x.ProjectId,
                        principalTable: "Projects",
                        principalColumn: "ProjectId",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_ProjectSkills_SkillTitles_SkillCode",
                        column: x => x.SkillCode,
                        principalTable: "SkillTitles",
                        principalColumn: "SkillCode",
                        onDelete: ReferentialAction.Cascade);
                });

            migrationBuilder.CreateIndex(
                name: "IX_ProjectSkills_SkillCode",
                table: "ProjectSkills",
                column: "SkillCode");

            migrationBuilder.CreateIndex(
                name: "IX_ProjectSkills_ProjectId_SkillCode",
                table: "ProjectSkills",
                columns: new[] { "ProjectId", "SkillCode" });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "ProjectSkills");

            migrationBuilder.DropTable(
                name: "SkillTitles");
        }
    }
}

有一些关键点需要考虑。

  1. SkillTitles表有一个主键SkillCode,它映射到Skill枚举中的值。
  2. ProjectSkills表有一个整数主键ProjectSkillId和两个外键ProjecId,用于链接到Project记录,SkillCode用于链接到SkillTitle记录。一些作者建议设置一个多值主键,ProjectIdSkillCode。这将为需要多种相同类型技能的项目设置一些问题。但是,我们设置了一个非唯一索引IX_ProjectSkills_ProjectId_SkillCode

我们稍后会看到其中的一些功能。现在将迁移到数据库。

Update-Database

SQL Server Management StudioSSMS)生成的下图显示了相关的数据库表。

客户——项目——技能数据库图

https://img-blog.csdnimg.cn/20181229152909608

 

现在我们在UI中包含这些实体。首先,我们在CustomerProjects Index页面中创建ProjectSkills的链接。

修改后的CustomerProject.cshtml

@page "{id:int?}"
@model QuantumWeb.Pages.Customers.CustomerProjectsModel
@{
    ViewData["Title"] = "Customer Projects";
}

<h2>Customer Projects</h2>

<div>
    <h4>Customer</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Customer.CustomerId)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Customer.CustomerId)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Customer.CustomerName)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Customer.CustomerName)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Customer.Projects)
        </dt>
        <dd>
            <table class="table">
                <tr>
                    <th>Project ID</th>
                    <th>Project Name</th>
                    <th>Project State</th>
                    <th></th>
                </tr>
                @foreach (var item in Model.Customer.Projects)
                {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.ProjectId)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ProjectName)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ProjectStateCode)
                    </td>
                    <td>
                        <a asp-page="./CustomerProjectSkills" asp-route-id="@item.ProjectId">
                            ProjectSkills
                        </a> |
                        <a asp-page="./CustomerProjectEdit" asp-route-id="@item.ProjectId">Edit</a> |
                        <a asp-page="./CustomerProjectDelete" asp-route-id="@item.ProjectId">Delete</a>
                    </td>
                </tr>
                }
            </table>
        </dd>
    </dl>
</div>

<div>
    <a asp-page="CustomerProjectCreate" asp-route-id="@Model.Customer.CustomerId">
        Create New Project
    </a> |
    <a asp-page="./Index">Back to List</a>
</div>

CustomerProjectSkills的链接要求我们构建一个新的Razor页面。

构建Customers/CustomerProjectSkills Razor页面

https://img-blog.csdnimg.cn/20181229152909657

初始化~Pages\Customers\CustomerProjectSkills.cshtml

@page "{id:int?}"
@model QuantumWeb.Pages.Customers.CustomerProjectSkillsModel
@{
    ViewData["Title"] = "Customer Project Skills";
}

<h2>Customer Project Skills</h2>

<p>
    <a asp-page="./CustomerProjects" asp-route-id="@Model.Customer.CustomerId">Back to List</a> |
    <a asp-page="CustomerProjectSkillAssign" asp-route-id="@Model.Project.ProjectId">Assign Skill</a>
</p>
<div>
    <h4>Customer-Project</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Customer.CustomerId)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Customer.CustomerId)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Customer.CustomerName)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Customer.CustomerName)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Project.ProjectId)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Project.ProjectId)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Project.ProjectName)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Project.ProjectName)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Project.ProjectSkills)
        </dt>
        <dd>
            <table class="table">
                <tr>
                    <th>Project Skill Id</th>
                    <th>Skill Code</th>
                    <th>Skill Title</th>
                    <th></th>
                </tr>
                @foreach (var item in Model.Project.ProjectSkills)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.ProjectSkillId)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.SkillCode)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.SkillTitle.Title)
                        </td>
                        <td>
                            <a asp-page="./CustomerProjectSkillDelete"
                              asp-route-id="@item.ProjectSkillId">
                                  Delete
                            </a>
                        </td>
                    </tr>
                }
            </table>
        </dd>
    </dl>
</div>

这会将页面配置为使用可为空的参数id,这将允许将目标ProjectProjectId传递给OnGet处理程序。有一个指向CustomerProjectSkillAssign页面的链接,该页面将创建一个ProjectSkill记录,有效地为项目分配技能。还有另一个指向CustomerProjectSkillDelete页面的链接,该页面将删除ProjectSkill记录。我们稍后会显示这两页的代码。

初始化~Pages\Customers\CustomerProjectSkills.cshtml.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using QuantumWeb.Data;
using QuantumWeb.Model;

namespace QuantumWeb.Pages.Customers
{
    public class CustomerProjectSkillsModel : PageModel
    {

        private readonly QuantumDbContext _context;

        public CustomerProjectSkillsModel(QuantumDbContext context)
        {
            _context = context;
        } // end public CustomerProjectSkillsModel(QuantumDbContext context)

        public Project Project { get; set; }
        public Customer Customer { get; set; }

        public async Task<IActionResult> OnGet(int? id)
        {
            if (id == null)
            {
                return NotFound();
            } // endif (id == null)

            Project = await _context.Projects
                .Include(p => p.Customer)
                .Include(p => p.ProjectSkills)
                    .ThenInclude(ps => ps.SkillTitle)
                    .FirstOrDefaultAsync(p => p.ProjectId == id);

            if (Project == null)
            {
                return NotFound();
            } // endif (Project == null)

            Customer = Project.Customer;

            return Page();
        } // end public async Task<IActionResult> OnGet(int? id)

    } // end public class CustomerProjectSkillsModel : PageModel

} // end namespace QuantumWeb.Pages.Customers

请注意实体框架(EF)预加载的示例。

           

 Project = await _context.Projects
                .Include(p => p.Customer)
                .Include(p => p.ProjectSkills)
                    .ThenInclude(ps => ps.SkillTitle)
                    .FirstOrDefaultAsync(p => p.ProjectId == id);

EF中,使用include()include扩展方法在单个查询中检索与预加载相关的实体。在这里,我们检索项目的相关CustomerProjectSkills实体,其ProjectId具有输入参数id的值。该查询更进一步使用ThenInclude()方法检索与检索到的ProjectSkills相关联的SkillTitles

接下来的几个屏幕截图显示了导航到此页面的顺序。

QuantumWeb应用程序主页:https//localhost:44306/

https://www.codeproject.com/KB/dotnet/1264741/QuantumWeb-Home-1-1.jpg

QuantumWeb应用程序客户索引页:https//localhost: 44306/Customers

https://img-blog.csdnimg.cn/20181229152909710

客户项目页面包含Mirarex Oil & Gas(已添加ProjectSkills链接)的2个项目

https://img-blog.csdnimg.cn/20181229152909710

Mirarex OilGasZolar Pipeline的客户项目技能页面(无技能)

https://img-blog.csdnimg.cn/20181229152909791

我们现在展示CustomerProjectSkillAssign Razor页面的构建。

构建Customers/CustomerProjectSkillAssign Razor页面

https://img-blog.csdnimg.cn/20181229152909845

初始化~Pages\Customers\CustomerProjectSkillAssign.cshtml.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using QuantumWeb.Data;
using QuantumWeb.Model;

namespace QuantumWeb.Pages.Customers
{
    public class CustomerProjectSkillAssignModel : PageModel
    {
        private readonly QuantumDbContext _context;

        public CustomerProjectSkillAssignModel(QuantumDbContext context)
        {
            _context = context;
        } // end public CustomerProjectSkillAssignModel(QuantumDbContext context)

        [BindProperty]
        public Project Project { get; set; }
        [BindProperty]
        public Customer Customer { get; set; }

        [BindProperty]
        public SkillTitle SkillTitle { get; set; }

        public async Task<IActionResult> OnGet(int? id)
        {
            if (id == null)
            {
                return NotFound();
            } // endif (id == null)

            Project = await _context.Projects
                .Include(p => p.Customer)
                .Include(p => p.ProjectSkills)
                    .ThenInclude(ps => ps.SkillTitle)
                    .FirstOrDefaultAsync(p => p.ProjectId == id);

            if (Project == null)
            {
                return NotFound();
            } // endif (Project == null)

            Customer = Project.Customer;

            ViewData["SkillCode"] = new SelectList(_context.SkillTitles, "SkillCode", "Title");

            return Page();
        }// end public async Task<IActionResult> OnGet(int? id)

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            } // endif (!ModelState.IsValid)

            ProjectSkill projectSkill = new ProjectSkill()
            {
                ProjectId = Project.ProjectId,
                SkillCode = SkillTitle.SkillCode
            };

            _context.ProjectSkills.Add(projectSkill);
            await _context.SaveChangesAsync();

            return RedirectToPage("./CustomerProjectSkills", new { id = Project.ProjectId });
        } // end public async Task<IActionResult> OnPostAsync()

    } // end public class CustomerProjectSkillAssignModel : PageModel

} // end namespace QuantumWeb.Pages.Customers

在这里,我们再次使用ViewData来设置选择列表,如第III部分所述。

ViewData["SkillCode"] = new SelectList(_context.SkillTitles, "SkillCode", "Title");

这次它处理SkillTitles以选择与项目关联的技能。

初始化~Pages\Customers\CustomerProjectSkillAssign.cshtml

@page "{id:int?}"
@model QuantumWeb.Pages.Customers.CustomerProjectSkillAssignModel
@{
    ViewData["Title"] = "Customer Project Skill Assignment";
}

<h2>Customer Project Skill Assignment</h2>
<hr />
<dl class="dl-horizontal">
    <dt>
        @Html.DisplayNameFor(model => model.Project.ProjectId)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Project.ProjectId)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.Project.ProjectName)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Project.ProjectName)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.Customer.CustomerId)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Customer.CustomerId)
    </dd>
    <dt>
        @Html.DisplayNameFor(model => model.Customer.CustomerName)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.Customer.CustomerName)
    </dd>
</dl>
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="Project.ProjectId" />
            <div class="form-group">
                <label asp-for="SkillTitle.SkillCode" class="control-label"></label>
                <select asp-for="SkillTitle.SkillCode" class="form-control" asp-items="ViewBag.SkillCode"></select>
            </div>
            <div class="form-group">
                <a asp-page="./CustomerProjectSkills" asp-route-id="Project.ProjectId">Project Skills</a> |
                <input type="submit" value="Assign" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

Zolar Pipeline的客户项目技能分配页面(技能选择打开)

https://www.codeproject.com/KB/dotnet/1264741/CustProjSkillAssign-01.jpg

Zolar Pipeline的客户项目技能分配页面(分配一个程序员)

https://img-blog.csdnimg.cn/20181229152909888

Mirarex OilGasZolar Pipeline的客户项目技能页面(程序员分配)

https://img-blog.csdnimg.cn/20181229152909888

分配了几个技能之后,这个页面看起来像:

Mirarex Oil & Gas, Zolar Pipeline 的客户项目技能页面(几项技能)

https://img-blog.csdnimg.cn/20181229152910121

管理层决定分配的程序员太多,因此我们需要删除一个。我们现在将构建CustomerProjectSkillDelete页面。

构建Customers/CustomerProjectSkillDelete Razor Page

https://www.codeproject.com/KB/dotnet/1264741/CreateCustProjSkillDelete-01.jpg

初始化~Pages\Customers\CustomerProjectSkillDelete.cshtml.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using QuantumWeb.Data;
using QuantumWeb.Model;

namespace QuantumWeb.Pages.Customers
{
    public class CustomerProjectSkillDeleteModel : PageModel
    {
        private readonly QuantumDbContext _context;

        public CustomerProjectSkillDeleteModel(QuantumDbContext context)
        {
            _context = context;
        } // end public CustomerProjectSkillDeleteModel(QuantumDbContext context)

        [BindProperty]
        public Customer Customer { get; set; }
        [BindProperty]
        public Project Project { get; set; }

        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id == null)
            {
                return NotFound();
            } // endif (id == null)

            Project = await _context.Projects
                .Include(p => p.Customer)
                    .FirstOrDefaultAsync(p => p.ProjectId == id);

            if (Project == null)
            {
                return NotFound();
            } // endif (Project == null)

            Customer = Project.Customer;

            return Page();
        } // end public async Task<IActionResult> OnGet(int? id)

        public async Task<IActionResult> OnPostAsync(int? id)
        {
            if (id == null)
            {
                return NotFound();
            } // endif (id == null)

            Project = await _context.Projects
                .Include(p => p.Customer)
                .FirstOrDefaultAsync(p => p.ProjectId == id);

            if (Project != null)
            {
                _context.Projects.Remove(Project);
                await _context.SaveChangesAsync();
            } // endif (Project != null)

            return RedirectToPage("./CustomerProjectSkills", new { id = Project.Customer.CustomerId });
        } // end public async Task<IActionResult> OnPostAsync(int? id)

    } // end public class CustomerProjectSkillDeleteModel : PageModel

} // end namespace QuantumWeb.Pages.Customers

初始化~Pages\Customers\CustomerProjectSkillDelete.cshtml

@page "{id:int?}"
@model QuantumWeb.Pages.Customers.CustomerProjectDeleteModel
@{
    ViewData["Title"] = "Delete Customer Project";
}

<h2>Delete Customer Project</h2>

<h3>Are you sure you want to delete this?</h3>
<div>
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Customer.CustomerName)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Customer.CustomerName)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Project.ProjectId)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Project.ProjectId)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Project.ProjectName)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Project.ProjectName)
        </dd>
        <dt>
            @Html.DisplayNameFor(model => model.Project.ProjectStateCode)
        </dt>
        <dd>
            @Html.DisplayFor(model => model.Project.ProjectStateCode)
        </dd>
    </dl>

    <form method="post">
        <input type="hidden" asp-for="Project.ProjectId" />
        <a asp-page="CustomerProjects" asp-route-id="@Model.Customer.CustomerId">Back to Customer Projects</a> |
        <input type="submit" value="Delete" class="btn btn-default" />
    </form>
</div>

Mirarex Oil & Gas, Zolar Pipeline客户项目技术删除页面 

https://img-blog.csdnimg.cn/20181229152910172

Mirarex OilGasZolar Pipeline的客户项目技能页面(已删除记录)

https://img-blog.csdnimg.cn/20181229152910238

 

原文地址:https://www.codeproject.com/Articles/1264741/ASP-NET-Core-Razor-Pages-Using-EntityFramework-C-3

猜你喜欢

转载自blog.csdn.net/mzl87/article/details/85339183