天天看點

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

目錄

介紹

背景

使用代碼

添加項目和項目技能處理

  • 下載下傳QuantumWeb-4.zip - 1.3 MB  

介紹

這是一篇由多部分組成的文章的第四部分,示範了通過EntityFramework Core 2.1(EF)将C#enum值映射到資料庫表中的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)

第三部分。建立Project和ProjectState實體,并在ProjectState和Projects之間實作一對多關系(https://blog.csdn.net/mzl87/article/details/85312583)

在第四部分:添加Skill 實體(Skill 枚舉,SkillTitle 和ProjectSkill)并實作Projects 和Skills之間的多對多關系,如下所示:

  • 添加實體Skill,SkillTitle和ProjectSkill并配置到QuantumDbContext中。
  • 添加遷移,添加項目技能實體和更新資料庫。
  • 搭建Skill相關的Razor頁面,CustomerProjectSkills.cshtml,CustomerProjectSkillAssign.cshtml和CustomerProjectSkillDelete.cshtml。運作測試以确認功能。

背景

本系列中實施的示例應用程式适用于虛拟工程技術公司,量子工程技術公司。這家公司主要服務于石油,天然氣和化學工業。到目前為止,我們已經讨論了對象模型的基礎,并建立了許多ASP.NET Razor頁面來處理客戶,項目和項目狀态。在最後一部分中,我們将讨論執行工作所需技能的清單。這項工作圍繞Skill枚舉和Skill與Projects之間的多對多關系建構。可能有許多項目需要某種技能。執行Project還需要很多Skill。是以,項目和技能實體之間存在多對多關系。

在關系資料庫中,通過為兩個實體建立連接配接表來實作多對多關系,如下所示。

通過連接配接表實作多對多關系

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

表A和表B之間存在多對多關系。在關系資料庫中,建立連接配接表JOIN-TABLE AB,與兩個表具有一對多關系。

在先前版本的實體架構(EF)中,可以按約定配置連接配接表,而無需在對象模型中使用實體或類。但是,截至目前為止,Entity Framework Core尚未提供此功能。(參見  https://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration。)是以,我們需要在對象模型中建立和配置一個類來實作這一目的。以下讨論顯示了如何使用相關的Razor頁面來管理UI中的内容。

使用代碼

工作對象模型顯示在第一部分中,并在此處針對 Skills重複。

Skills的工作對象模型

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

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執行個體的引用。ProjectId和SkillCode屬性将映射到資料庫中ProjectSkills表中的外鍵。另請注意,SkillTitle類具有集合屬性ProjectSkills(List <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
           

這裡我們定義DbSets,SkillTitles和ProjectSkills,并添加SkillTitleConfiguration和ProjectSkillConfiguration類以便在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記錄。一些作者建議設定一個多值主鍵,ProjectId和SkillCode。這将為需要多種相同類型技能的項目設定一些問題。但是,我們設定了一個非唯一索引IX_ProjectSkills_ProjectId_SkillCode。

我們稍後會看到其中的一些功能。現在将遷移到資料庫。

Update-Database
           

從SQL Server Management Studio(SSMS)生成的下圖顯示了相關的資料庫表。

客戶——項目——技能資料庫圖

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

現在我們在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頁面

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

初始化~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,這将允許将目标Project的ProjectId傳遞給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擴充方法在單個查詢中檢索與預加載相關的實體。在這裡,我們檢索項目的相關Customer和ProjectSkills實體,其ProjectId具有輸入參數id的值。該查詢更進一步使用ThenInclude()方法檢索與檢索到的ProjectSkills相關聯的SkillTitles。

接下來的幾個螢幕截圖顯示了導航到此頁面的順序。

QuantumWeb應用程式首頁:https//localhost:44306/

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

QuantumWeb應用程式客戶索引頁:https//localhost: 44306/Customers

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

客戶項目頁面包含Mirarex Oil & Gas(已添加ProjectSkills連結)的2個項目

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

Mirarex Oil&Gas,Zolar Pipeline的客戶項目技能頁面(無技能)

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

我們現在展示CustomerProjectSkillAssign Razor頁面的建構。

建構Customers/CustomerProjectSkillAssign Razor頁面

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

初始化~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部分所述。(譯者注:此處和上一篇中枚舉映射下拉框一樣,需要手動在資料庫表SkillTitles中添加對應的Skill枚舉值和标題描述資訊)

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的客戶項目技能配置設定頁面(技能選擇打開)

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

Zolar Pipeline的客戶項目技能配置設定頁面(配置設定一個程式員)

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

Mirarex Oil&Gas,Zolar Pipeline的客戶項目技能頁面(程式員配置設定)

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

配置設定了幾個技能之後,這個頁面看起來像:

Mirarex Oil & Gas, Zolar Pipeline 的客戶項目技能頁面(幾項技能)

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

管理層決定配置設定的程式員太多,是以我們需要删除一個。我們現在将建構CustomerProjectSkillDelete頁面。

建構Customers/CustomerProjectSkillDelete Razor Page

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

初始化~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的客戶項目技術删除頁面 

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

Mirarex Oil&Gas,Zolar Pipeline的客戶項目技能頁面(已删除記錄)

使用EntityFramework Core和Enums作為字元串的ASP.NET Core Razor頁面——第四部分介紹背景使用代碼

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

繼續閱讀