目录

介绍

使用代码


添加项目和项目状态处理

介绍

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

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

第一部分。设置实体框架数据上下文和初始Customer的Razor页面

第二部分。完成了Customers的CRUD功能

在第三部分。我们将创建Project和ProjectState实体并在ProjectState和Project之间实现一个一对多的关系,如下:

  • 添加Project,ProjectState和ProjectStateDescription实体。
  • 添加EF迁移以在数据库中创建和配置Projects和ProjectStateDescriptions表。
  • 演示enum对象模型实体中的string值与Projects和ProjectStateDescriptions数据库表中的值之间的转换。
  • 搭建,实现和测试包含ProjectState功能的ProjectCRUD页面,如CustomerProjects.cshtmlCustomerProjectCreate.cshtmlCustomerProjectDetails.cshtmlCustomerProjectDelete.cshtml Razor页面。

使用代码

添加初始项目处理。

接下来,我们启用Customer项目处理。该应用程序使用Customer作为“网关”实体; 一切都是通过Customer。Customer和Projects之间存在一对多的关系。因此,我们需要修改Customer类。

修改后的Customer.cs

  1.  
    using System.Collections.Generic;
  2.  
     
  3.  
    namespace QuantumWeb.Model
  4.  
    {
  5.  
    /// <summary>
  6.  
    /// Customer Class
  7.  
    /// </summary>
  8.  
    public class Customer
  9.  
    {
  10.  
    #region Constructors
  11.  
     
  12.  
    /// <summary>
  13.  
    /// Parameter-less Constructor
  14.  
    /// </summary>
  15.  
    /// <remarks>
  16.  
    /// Required for scaffolding the UI
  17.  
    /// </remarks>
  18.  
    public Customer()
  19.  
    {
  20.  
    } // end public Customer()
  21.  
     
  22.  
    #endregion // Constructors
  23.  
     
  24.  
    /// <summary>
  25.  
    /// Customer Identifier, primary key
  26.  
    /// </summary>
  27.  
    public int CustomerId { get; set; }
  28.  
    /// <summary>
  29.  
    /// Customer Name
  30.  
    /// </summary>
  31.  
    public string CustomerName { get; set; }
  32.  
    /// <summary>
  33.  
    /// Primary Customer Contact
  34.  
    /// </summary>
  35.  
    public string CustomerContact { get; set; }
  36.  
    /// <summary>
  37.  
    /// Customer Contact Phone Number
  38.  
    /// </summary>
  39.  
    public string CustomerPhone { get; set; }
  40.  
    /// <summary>
  41.  
    /// Customer Contact Email Address
  42.  
    /// </summary>
  43.  
    public string CustomerEmail { get; set; }
  44.  
     
  45.  
    #region Navigation Properties
  46.  
     
  47.  
    /// <summary>
  48.  
    /// List of Projects
  49.  
    /// </summary>
  50.  
    public List<Project> Projects { get; set; }
  51.  
     
  52.  
    #endregion // Navigation Properties
  53.  
     
  54.  
    } // end public class Customer
  55.  
     
  56.  
    } // end namespace QuantumWeb.Model

我们添加了一个项目列表。在这里,我们将某些属性标识为导航属性。这些属性引用其他类/实体,以便我们可以在处理中导航到它们。Customer在Projects列表中表示零或多个Projects。初始Project类定义如下。

初始Project.cs

  1.  
    namespace QuantumWeb.Model
  2.  
    {
  3.  
    /// <summary>
  4.  
    /// Project Class
  5.  
    /// </summary>
  6.  
    public class Project
  7.  
    {
  8.  
    /// <summary>
  9.  
    /// Project Identifier, primary key
  10.  
    /// </summary>
  11.  
    public int ProjectId { get; set; }
  12.  
    /// <summary>
  13.  
    /// Project Name
  14.  
    /// </summary>
  15.  
    public string ProjectName { get; set; }
  16.  
     
  17.  
    #region Navigation Properties
  18.  
     
  19.  
    /// <summary>
  20.  
    /// Customer Identifier
  21.  
    /// </summary>
  22.  
    public int CustomerId { get; set; }
  23.  
     
  24.  
    /// <summary>
  25.  
    /// Customer
  26.  
    /// </summary>
  27.  
    /// <remarks>
  28.  
    /// Every Project has a Customer
  29.  
    /// </remarks>
  30.  
    public Customer Customer { get; set; }
  31.  
     
  32.  
    /// <summary>
  33.  
    /// Project Status Code
  34.  
    /// </summary>
  35.  
    public ProjectState ProjectStateCode { get; set; }
  36.  
     
  37.  
    /// <summary>
  38.  
    /// ProjectStateDescription Reference
  39.  
    /// </summary>
  40.  
    public ProjectStateDescription ProjectStateDescription { get; set; }
  41.  
     
  42.  
    #endregion // Navigation Properties
  43.  
     
  44.  
    } // end public class Project
  45.  
     
  46.  
    } // end namespace QuantumApp.Model

除了定义初始化Project类之外,我们还将在Model文件夹中定义ProjectState enum。

ProjectState.cs

  1.  
    namespace QuantumWeb.Model
  2.  
    {
  3.  
    /// <summary>
  4.  
    /// Project State Enumeration
  5.  
    /// </summary>
  6.  
    public enum ProjectState
  7.  
    {
  8.  
    Prospect,
  9.  
    UnderReview,
  10.  
    StartScheduled,
  11.  
    InProgress,
  12.  
    Completed
  13.  
    } // end public enum ProjectState
  14.  
     
  15.  
    } // end namespace QuantumWeb.Model

这个enum指定了Project工作流的状态。

  • Prospect。这涉及一个有前景的Project。这个Project可能是通过推荐或其他营销工作提出的。尚未进行任何研究,且规格尚不清楚。
  • UnderReview。在这种状态下,Project制定了要求,初始预算和进度表。没有承诺Quantum或者Customer。
  • StartScheduled。已经指定了工作开始的日期,并且正在准备开始工作。
  • InProgress。实际工作已经开始但尚未完成。
  • Completed。项目工作完成。

如前所述,我们对此应用程序有两个目标。

  1. 我们应该为Project将在UI中显示的每个状态定义简短描述,以帮助用户理解每个状态的含义。
  2. 每个enum值都作为string类型存储在数据库中。

为了满足ProjectState enum的这些要求,我们定义了ProjectStateDescription类。

ProjectStateDescription.cs

  1.  
    using System.Collections.Generic;
  2.  
     
  3.  
    namespace QuantumWeb.Model
  4.  
    {
  5.  
    /// <summary>
  6.  
    /// Project State Description Class
  7.  
    /// </summary>
  8.  
    public class ProjectStateDescription
  9.  
    {
  10.  
    /// <summary>
  11.  
    /// ProjectState Code
  12.  
    /// </summary>
  13.  
    public ProjectState ProjectStateCode { get; set; }
  14.  
     
  15.  
    /// <summary>
  16.  
    /// State Description
  17.  
    /// </summary>
  18.  
    public string StateDescription { get; set; }
  19.  
     
  20.  
    #region Navigation Properties
  21.  
     
  22.  
    /// <summary>
  23.  
    /// Projects Collection
  24.  
    /// </summary>
  25.  
    public List<Project> Projects { get; set; }
  26.  
     
  27.  
    #endregion // Navigation Properties
  28.  
     
  29.  
    } // end public class ProjectStateDescription
  30.  
     
  31.  
    } // end namespace QuantumWeb.Model

ProjectState对Projects的一对多的关系,通过导航属性启用。每个Project都有一个ProjectStateDesciption。每个ProjectStateDescripton都有一个Projects集合。

接下来,我们需要为Project和ProjectStateDescription定义EF配置类,并在QuantumDbContext类中包含所有内容。所有此活动都发生在Data文件夹中。

初始ProjectConfiguration.cs

  1.  
    using System;
  2.  
    using Microsoft.EntityFrameworkCore;
  3.  
    using Microsoft.EntityFrameworkCore.Metadata.Builders;
  4.  
    using QuantumWeb.Model;
  5.  
     
  6.  
    namespace QuantumWeb.Data
  7.  
    {
  8.  
    public class ProjectConfiguration : IEntityTypeConfiguration<Project>
  9.  
    {
  10.  
    public void Configure(EntityTypeBuilder<Project> builder)
  11.  
    {
  12.  
    builder.ToTable("Projects");
  13.  
    builder.HasKey(p => p.ProjectId);
  14.  
    builder.Property(p => p.ProjectId)
  15.  
    .HasColumnType("int");
  16.  
    builder.Property(p => p.ProjectName)
  17.  
    .IsRequired()
  18.  
    .HasColumnType("nvarchar(80)")
  19.  
    .HasMaxLength(80);
  20.  
    builder.Property(p => p.CustomerId)
  21.  
    .HasColumnType("int")
  22.  
    .IsRequired();
  23.  
    builder.HasOne(p => p.Customer)
  24.  
    .WithMany(c => c.Projects)
  25.  
    .HasForeignKey(p => p.CustomerId)
  26.  
    .IsRequired();
  27.  
    builder.Property(p => p.ProjectStateCode)
  28.  
    .HasColumnType("nvarchar(15)")
  29.  
    .HasDefaultValue(ProjectState.Prospect)
  30.  
    .HasConversion(
  31.  
    p => p.ToString(),
  32.  
    p => (ProjectState)Enum.Parse(typeof(ProjectState), p));
  33.  
    builder.HasOne(p => p.ProjectStateDescription)
  34.  
    .WithMany(pd => pd.Projects)
  35.  
    .HasForeignKey(p => p.ProjectStateCode);
  36.  
    } // end public void Configure(EntityTypeBuilder<Project> builder)
  37.  
     
  38.  
    } // end public class ProjectConfiguration : IEntityTypeConfiguration<Project>
  39.  
     
  40.  
    } // end namespace QuantumWeb.Data

看看下面提取的行:

  1.  
    builder.HasOne(p => p.Customer)
  2.  
    .WithMany(c => c.Projects)
  3.  
    .HasForeignKey(p => p.CustomerId)
  4.  
    .IsRequired();

对这些行的解释是,“每个Project都有一个带有许多Projects的Customer。每个Project都映射到Projects数据库中的表,通过外键CustomerId,并且这是必需的。因此,Customer- Project关系是一对多。

在一对多ProjectStateDescription- Project关系被配置为:

  1.  
    builder.HasOne(p => p.ProjectStateDescription)
  2.  
    .WithMany(pd => pd.Projects)
  3.  
    .HasForeignKey(p => p.ProjectStateCode);

接下来,我们将了解处理enum的值到数据库string列配置的方式。

  1.  
    builder.Property(p => p.ProjectStateCode)
  2.  
    .HasColumnType("nvarchar(15)")
  3.  
    .HasDefaultValue(ProjectState.Prospect)
  4.  
    .HasConversion(
  5.  
    p => p.ToString(),
  6.  
    p => (ProjectState)Enum.Parse(typeof(ProjectState), p));

这些行首先在Projects名为的表中配置一个列ProjectStateCode,类型为nvarchar(15),其默认值来自ProjectState.Prospect。接下来,定义ProjectState值和string值之间的转换。当将值从ProjectState enum移动到Projects表时,将使用该ToString()函数转换值。换另一种方式时,表中string的值将被解析为一个enum值。始终使用相同的方案在数据库列中的enum值和string值之间进行转换。

ProjectStateDescriptionConfiguration类如下所示。

ProjectStateDescriptionConfiguration.cs

  1.  
    using System;
  2.  
    using Microsoft.EntityFrameworkCore;
  3.  
    using Microsoft.EntityFrameworkCore.Metadata.Builders;
  4.  
    using QuantumWeb.Model;
  5.  
     
  6.  
    namespace QuantumWeb.Data
  7.  
    {
  8.  
    /// <summary>
  9.  
    /// ProjectState Description Configuration Class
  10.  
    /// </summary>
  11.  
    public class ProjectStateDescriptionConfiguration :
  12.  
    IEntityTypeConfiguration<ProjectStateDescription>
  13.  
    {
  14.  
     
  15.  
    public void Configure(EntityTypeBuilder<ProjectStateDescription> builder)
  16.  
    {
  17.  
    builder.ToTable("ProjectStateDescriptions");
  18.  
    builder.HasKey(p => p.ProjectStateCode);
  19.  
    builder.Property(p => p.ProjectStateCode)
  20.  
    .HasColumnType("nvarchar(15)")
  21.  
    .HasConversion(
  22.  
    p => p.ToString(),
  23.  
    p => (ProjectState)Enum.Parse(typeof(ProjectState), p));
  24.  
    builder.Property(p => p.StateDescription)
  25.  
    .IsRequired()
  26.  
    .HasColumnType("nvarchar(80)")
  27.  
    .HasMaxLength(80);
  28.  
    } // end public void Configure(EntityTypeBuilder<ProjectStateDescription> builder)
  29.  
     
  30.  
    } // end public class ProjectStateDescriptionConfiguration :
  31.  
    // IEntityTypeConfiguration<ProjectStateDescription>
  32.  
     
  33.  
    } // end namespace QuantumWeb.Data

现在,我们更新QuantumDbContext类。

然后更新QuantumDbContext.cs

  1.  
    using Microsoft.EntityFrameworkCore;
  2.  
    using QuantumWeb.Model;
  3.  
     
  4.  
    namespace QuantumWeb.Data
  5.  
    {
  6.  
    public class QuantumDbContext : DbContext
  7.  
    {
  8.  
    public QuantumDbContext (DbContextOptions<QuantumDbContext> options)
  9.  
    : base(options)
  10.  
    {
  11.  
    } // end public QuantumDbContext (DbContextOptions<QuantumDbContext> options)
  12.  
     
  13.  
    #region DbSets
  14.  
     
  15.  
    /// <summary>
  16.  
    /// Customer DbSet
  17.  
    /// </summary>
  18.  
    public DbSet<Customer> Customers { get; set; }
  19.  
     
  20.  
    /// <summary>
  21.  
    /// Project DbSet
  22.  
    /// </summary>
  23.  
    public DbSet<Project> Projects { get; set; }
  24.  
     
  25.  
    /// <summary>
  26.  
    /// ProjectStateDescription DbSet
  27.  
    /// </summary>
  28.  
    public DbSet<ProjectStateDescription> ProjectStateDescriptions { get; set; }
  29.  
     
  30.  
    #endregion // DbSets
  31.  
     
  32.  
    /// <summary>
  33.  
    /// Data Model Creation Method
  34.  
    /// </summary>
  35.  
    /// <param name="modelBuilder">ModelBuilder instance</param>
  36.  
    protected override void OnModelCreating(ModelBuilder modelBuilder)
  37.  
    {
  38.  
    modelBuilder.ApplyConfiguration(new CustomerConfiguration());
  39.  
    modelBuilder.ApplyConfiguration(new ProjectConfiguration());
  40.  
    modelBuilder.ApplyConfiguration(new ProjectStateDescriptionConfiguration());
  41.  
    } // end protected override void OnModelCreating(ModelBuilder modelBuilder)
  42.  
     
  43.  
    } // end public class QuantumDbContext : DbContext
  44.  
     
  45.  
    } // end namespace QuantumWeb.Data

现在为Project和ProjectState实体添加EF迁移。(译者注:同样需要调整appsettings.json中数据库连接字符串,建议删除Migrations文件夹后在执行下面的命令,同时提醒,在执行下面命令后需要命令update-database更新到数据库)

Add-Migration Added-Project-ProjectState

生成 ~\Migrations\20181021203503_Added-Project-ProjectState.cs:

  1.  
    using Microsoft.EntityFrameworkCore.Metadata;
  2.  
    using Microsoft.EntityFrameworkCore.Migrations;
  3.  
     
  4.  
    namespace QuantumWeb.Migrations
  5.  
    {
  6.  
    public partial class AddedProjectProjectState : Migration
  7.  
    {
  8.  
    protected override void Up(MigrationBuilder migrationBuilder)
  9.  
    {
  10.  
    migrationBuilder.CreateTable(
  11.  
    name: "ProjectStateDescriptions",
  12.  
    columns: table => new
  13.  
    {
  14.  
    ProjectStateCode =
  15.  
    table.Column<string>(type: "nvarchar(15)", nullable: false),
  16.  
    StateDescription =
  17.  
    table.Column<string>(type: "nvarchar(80)", maxLength: 80, nullable: false)
  18.  
    },
  19.  
    constraints: table =>
  20.  
    {
  21.  
    table.PrimaryKey("PK_ProjectStateDescriptions", x => x.ProjectStateCode);
  22.  
    });
  23.  
     
  24.  
    migrationBuilder.CreateTable(
  25.  
    name: "Projects",
  26.  
    columns: table => new
  27.  
    {
  28.  
    ProjectId = table.Column<int>(type: "int", nullable: false)
  29.  
    .Annotation("SqlServer:ValueGenerationStrategy",
  30.  
    SqlServerValueGenerationStrategy.IdentityColumn),
  31.  
    ProjectName = table.Column<string>(type: "nvarchar(80)",
  32.  
    maxLength: 80, nullable: false),
  33.  
    CustomerId = table.Column<int>(type: "int", nullable: false),
  34.  
    ProjectStateCode = table.Column<string>
  35.  
    (type: "nvarchar(15)", nullable: false, defaultValue: "Prospect")
  36.  
    },
  37.  
    constraints: table =>
  38.  
    {
  39.  
    table.PrimaryKey("PK_Projects", x => x.ProjectId);
  40.  
    table.ForeignKey(
  41.  
    name: "FK_Projects_Customers_CustomerId",
  42.  
    column: x => x.CustomerId,
  43.  
    principalTable: "Customers",
  44.  
    principalColumn: "CustomerId",
  45.  
    onDelete: ReferentialAction.Cascade);
  46.  
    table.ForeignKey(
  47.  
    name: "FK_Projects_ProjectStateDescriptions_ProjectStateCode",
  48.  
    column: x => x.ProjectStateCode,
  49.  
    principalTable: "ProjectStateDescriptions",
  50.  
    principalColumn: "ProjectStateCode",
  51.  
    onDelete: ReferentialAction.Cascade);
  52.  
    });
  53.  
     
  54.  
    migrationBuilder.CreateIndex(
  55.  
    name: "IX_Projects_CustomerId",
  56.  
    table: "Projects",
  57.  
    column: "CustomerId");
  58.  
     
  59.  
    migrationBuilder.CreateIndex(
  60.  
    name: "IX_Projects_ProjectStateCode",
  61.  
    table: "Projects",
  62.  
    column: "ProjectStateCode");
  63.  
    }
  64.  
     
  65.  
    protected override void Down(MigrationBuilder migrationBuilder)
  66.  
    {
  67.  
    migrationBuilder.DropTable(
  68.  
    name: "Projects");
  69.  
     
  70.  
    migrationBuilder.DropTable(
  71.  
    name: "ProjectStateDescriptions");
  72.  
    }
  73.  
    }
  74.  
    }

在Update- Database命令之后,SQL Server Management Studio(SSMS)中的数据库关系图如下所示。

使用Customer- Project- ProjectState表的QuantumDbContext数据库关系图:

修改Project和ProjectState的Razor 页。

我们需要为项目的应用程序添加一些自定义客户Razor 页面。首先,我们需要为CustomerProjects添加一个指向Customer/Index页面的链接。

添加CustomerProjects 链接指向Pages\Customers\Index.cshtml:

  1.  
    @page
  2.  
    @model QuantumWeb.Pages.Customers.IndexModel
  3.  
     
  4.  
    @{
  5.  
    ViewData["Title"] = "Index";
  6.  
    }
  7.  
     
  8.  
    <h2>Index</h2>
  9.  
     
  10.  
    <p>
  11.  
    <a asp-page="Create">Create New</a>
  12.  
    <!-- A link to the Pages/Customers/Create page to create a new Customer -->
  13.  
    </p>
  14.  
    <!-- An HTML table to display existing Customers -->
  15.  
    <table class="table">
  16.  
    <thead>
  17.  
    <tr>
  18.  
    <th>
  19.  
    @Html.DisplayNameFor(model => model.Customer[0].CustomerName)
  20.  
    </th>
  21.  
    <th>
  22.  
    @Html.DisplayNameFor(model => model.Customer[0].CustomerContact)
  23.  
    </th>
  24.  
    <th>
  25.  
    @Html.DisplayNameFor(model => model.Customer[0].CustomerPhone)
  26.  
    </th>
  27.  
    <th>
  28.  
    @Html.DisplayNameFor(model => model.Customer[0].CustomerEmail)
  29.  
    </th>
  30.  
    <th></th>
  31.  
    </tr>
  32.  
    </thead>
  33.  
    <tbody>
  34.  
    @foreach (var item in Model.Customer) {
  35.  
    <tr>
  36.  
    <td>
  37.  
    @Html.DisplayFor(modelItem => item.CustomerName)
  38.  
    </td>
  39.  
    <td>
  40.  
    @Html.DisplayFor(modelItem => item.CustomerContact)
  41.  
    </td>
  42.  
    <td>
  43.  
    @Html.DisplayFor(modelItem => item.CustomerPhone)
  44.  
    </td>
  45.  
    <td>
  46.  
    @Html.DisplayFor(modelItem => item.CustomerEmail)
  47.  
    </td>
  48.  
    <td>
  49.  
    <a asp-page="./Edit" asp-route-id="@item.CustomerId">Edit</a> |
  50.  
    <!-- A link to the Pages/Customers/Edit page to edit an existing Customer -->
  51.  
    <a asp-page="./Details" asp-route-id="@item.CustomerId">Details</a> |
  52.  
    <!--
  53.  
    A link to the Pages/Customers/Details page to display the details for an existing
  54.  
    Customer
  55.  
    -->
  56.  
    <a asp-page="./CustomerProjects" asp-route-id="@item.CustomerId">Projects</a> |
  57.  
    <!--
  58.  
    A link to the Pages/Customers/CustomerProjects page to display & manage the
  59.  
    Projects for an existing Customer
  60.  
    -->
  61.  
    <a asp-page="./Delete" asp-route-id="@item.CustomerId">Delete</a>
  62.  
    <!-- A link to the Pages/Customers/Delete page to delete an existing Customer -->
  63.  
    </td>
  64.  
    </tr>
  65.  
    }
  66.  
    </tbody>
  67.  
    </table>

我们将如下构建几个自定义Customers Razor页面。

为客户设计的定制构建Razor页面:

搭建Customers/CustomerProjects Razor 页面:

单击“ 添加 ”将为CustomerProjects Index页面生成shell文件。

生成~Pages\Customers\CustomerProjects.cshtml

  1.  
    @page
  2.  
    @model QuantumWeb.Pages.Customers.CustomerProjectsModel
  3.  
    @{
  4.  
    ViewData["Title"] = "CustomerProjects";
  5.  
    }
  6.  
     
  7.  
    <h2>CustomerProjects</h2>

生成~Pages\Customers\CustomerProjects.cshtml.cs

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Linq;
  4.  
    using System.Threading.Tasks;
  5.  
    using Microsoft.AspNetCore.Mvc;
  6.  
    using Microsoft.AspNetCore.Mvc.RazorPages;
  7.  
     
  8.  
    namespace QuantumWeb.Pages.Customers
  9.  
    {
  10.  
    public class CustomerProjectsModel : PageModel
  11.  
    {
  12.  
    public void OnGet()
  13.  
    {
  14.  
     
  15.  
    }
  16.  
    }
  17.  
    }

我们将在每种情况下修改这些shell文件以满足我们的需求。CustomerProjects Index 页面的修改文件。

修改了~Pages\Customers\CustomerProjects.cshtml

  1.  
    @page "{id:int?}"
  2.  
    @model QuantumWeb.Pages.Customers.CustomerProjectsModel
  3.  
    @{
  4.  
    ViewData["Title"] = "Customer Projects";
  5.  
    }
  6.  
     
  7.  
    <h2>Customer Projects</h2>
  8.  
     
  9.  
    <div>
  10.  
    <h4>Customer</h4>
  11.  
    <hr />
  12.  
    <dl class="dl-horizontal">
  13.  
    <dt>
  14.  
    @Html.DisplayNameFor(model => model.Customer.CustomerId)
  15.  
    </dt>
  16.  
    <dd>
  17.  
    @Html.DisplayFor(model => model.Customer.CustomerId)
  18.  
    </dd>
  19.  
    <dt>
  20.  
    @Html.DisplayNameFor(model => model.Customer.CustomerName)
  21.  
    </dt>
  22.  
    <dd>
  23.  
    @Html.DisplayFor(model => model.Customer.CustomerName)
  24.  
    </dd>
  25.  
    <dt>
  26.  
    @Html.DisplayNameFor(model => model.Customer.Projects)
  27.  
    </dt>
  28.  
    <dd>
  29.  
    <table class="table">
  30.  
    <tr>
  31.  
    <th>Project ID</th>
  32.  
    <th>Project Name</th>
  33.  
    <th>Project State</th>
  34.  
    <th></th>
  35.  
    </tr>
  36.  
    @foreach (var item in Model.Customer.Projects)
  37.  
    {
  38.  
    <tr>
  39.  
    <td>
  40.  
    @Html.DisplayFor(modelItem => item.ProjectId)
  41.  
    </td>
  42.  
    <td>
  43.  
    @Html.DisplayFor(modelItem => item.ProjectName)
  44.  
    </td>
  45.  
    <td>
  46.  
    @Html.DisplayFor(modelItem => item.ProjectStateCode)
  47.  
    </td>
  48.  
    <td>
  49.  
    <a asp-page="./CustomerProjectEdit"
  50.  
     
  51.  
    asp-route-id="@item.ProjectId">Edit</a> |
  52.  
    <a asp-page="./CustomerProjectDelete"
  53.  
     
  54.  
    asp-route-id="@item.ProjectId">Delete</a>
  55.  
    </td>
  56.  
    </tr>
  57.  
    }
  58.  
    </table>
  59.  
    </dd>
  60.  
    </dl>
  61.  
    </div>
  62.  
     
  63.  
    <div>
  64.  
    <a asp-page="CustomerProjectCreate" asp-route-id="@Model.Customer.CustomerId">
  65.  
    Create New Project</a> |
  66.  
    <a asp-page="./Index">Back to List</a>
  67.  
    </div>

“ {id:int?}”表示需要整数参数,id需要或者请求页面将返回HTTP 401(未找到页面)错误。在这种情况下,这是目标Customer的标识符(CustomerId)。另外,请注意引用该CustomerProjectCreate页面的链接。

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

这将把我们带到CustomerProjectCreate尚未创建的页面,为引用Customer创建一个新的Project。

修改了~Pages\Customers\CustomerProjects.cshtml.cs

  1.  
    using System.Threading.Tasks;
  2.  
    using Microsoft.AspNetCore.Mvc;
  3.  
    using Microsoft.AspNetCore.Mvc.RazorPages;
  4.  
    using Microsoft.EntityFrameworkCore;
  5.  
    using QuantumWeb.Data;
  6.  
    using QuantumWeb.Model;
  7.  
     
  8.  
    namespace QuantumWeb.Pages.Customers
  9.  
    {
  10.  
    public class CustomerProjectsModel : PageModel
  11.  
    {
  12.  
    private readonly QuantumDbContext _context;
  13.  
     
  14.  
    public CustomerProjectsModel(QuantumDbContext context)
  15.  
    {
  16.  
    _context = context;
  17.  
    } // end public CustomerProjectsModel(QuantumDbContext context)
  18.  
     
  19.  
    public Customer Customer { get; set; }
  20.  
     
  21.  
    public async Task<IActionResult> OnGet(int? id)
  22.  
    {
  23.  
    if (id == null)
  24.  
    {
  25.  
    return NotFound();
  26.  
    } // endif (id == null)
  27.  
     
  28.  
    Customer = await _context.Customers
  29.  
    .Include(c => c.Projects)
  30.  
    .FirstOrDefaultAsync(c => c.CustomerId == id);
  31.  
     
  32.  
    if (Customer == null)
  33.  
    {
  34.  
    return NotFound();
  35.  
    } // endif (Customer == null)
  36.  
     
  37.  
    return Page();
  38.  
    } // end public async Task<IActionResult> OnGet(int? id)
  39.  
     
  40.  
    } // end public class CustomerProjectsModel : PageModel
  41.  
     
  42.  
    } // end namespace QuantumWeb.Pages.Customers

请注意,OnGet处理程序具有可为空的整数参数,id应该是如上所述的CustomerId。

QuantumWeb 应用客户页面: https//localhost: 44306/Customers 具有项目链接。

Customer Projects页面:https//localhost: 44306/Customers/CustomerProjects/1(无项目)

“ 创建新项目 ”链接将激活自定义CustomerProjectCreate Razor页面。我们现在搭建这个页面。

搭建Customers/CustomerProjectCreate Razor页面:

Initial~Pages\Customers\CustomerProjectCreate.cshtml.cs

  1.  
    using System.Threading.Tasks;
  2.  
    using Microsoft.AspNetCore.Mvc;
  3.  
    using Microsoft.AspNetCore.Mvc.RazorPages;
  4.  
    using Microsoft.AspNetCore.Mvc.Rendering;
  5.  
    using Microsoft.EntityFrameworkCore;
  6.  
    using QuantumWeb.Data;
  7.  
    using QuantumWeb.Model;
  8.  
     
  9.  
    namespace QuantumWeb.Pages.Customers
  10.  
    {
  11.  
    public class CustomerProjectCreateModel : PageModel
  12.  
    {
  13.  
    private readonly QuantumDbContext _context;
  14.  
     
  15.  
    public CustomerProjectCreateModel(QuantumDbContext context)
  16.  
    {
  17.  
    _context = context;
  18.  
    } // end public CustomerProjectCreateModel(QuantumContext context)
  19.  
     
  20.  
    [BindProperty]
  21.  
    public Customer Customer { get; set; }
  22.  
     
  23.  
    public async Task<IActionResult> OnGet(int? id)
  24.  
    {
  25.  
    if (id == null)
  26.  
    {
  27.  
    return NotFound();
  28.  
    } // endif (id == null)
  29.  
     
  30.  
    Customer = await _context.Customers
  31.  
    .Include(c => c.Projects)
  32.  
    .FirstOrDefaultAsync(c => c.CustomerId == id);
  33.  
     
  34.  
    if (Customer == null)
  35.  
    {
  36.  
    return NotFound();
  37.  
    } // endif (Customer == null)
  38.  
     
  39.  
    ViewData["ProjectStateCode"] = new SelectList(_context.ProjectStateDescriptions,
  40.  
    "ProjectStateCode", "StateDescription", ProjectState.Prospect);
  41.  
     
  42.  
    return Page();
  43.  
     
  44.  
    } // end public async Task<IActionResult> OnGet(int? id)
  45.  
     
  46.  
    [BindProperty]
  47.  
    public Project Project { get; set; }
  48.  
     
  49.  
    public async Task<IActionResult> OnPostAsync()
  50.  
    {
  51.  
    if (!ModelState.IsValid)
  52.  
    {
  53.  
    return Page();
  54.  
    } // endif (!ModelState.IsValid)
  55.  
     
  56.  
    Project.CustomerId = Customer.CustomerId;
  57.  
     
  58.  
    _context.Projects.Add(Project);
  59.  
    await _context.SaveChangesAsync();
  60.  
     
  61.  
    return RedirectToPage("./CustomerProjects", new { id = Customer.CustomerId });
  62.  
    } // end public async Task<IActionResult> OnPostAsync()
  63.  
     
  64.  
    } // end public class CustomerProjectCreateModel : PageModel
  65.  
     
  66.  
    } // end namespace QuantumWeb.Pages.Customers

请注意此代码中的这些行。

  1.  
    [BindProperty]
  2.  
    public Customer Customer { get; set; }

该[BindProperty]将Customer实例绑定到UI的元素,以便在浏览器和Web服务器之间保留它们的值。另请注意,此属性也适用于Project实例。

  1.  
    Customer = await _context.Customers
  2.  
    .Include(c => c.Projects)
  3.  
    .FirstOrDefaultAsync(c => c.CustomerId == id);

此语句对数据库执行查询,以检索Customer其主键值CustomerId与输入参数id值及其关联Project记录匹配的记录。如果有,该.Include函数的功能是查询中包含相关记录。

  1.  
    ViewData["ProjectStateCode"] = new SelectList(_context.ProjectStateDescriptions,
  2.  
    "ProjectStateCode", "StateDescription", ProjectState.Prospect);

ViewData是一个无类型的键值字典,用于在CustomerProjectCreateModel类(在.cshtml.cs文件中)和.cshtml文件中的HTML 之间传递值。这类似于MVC中将数据从Controller 传递到View,在使用ViewData中,数据仅在HTTP请求中持久存在。其成员由ProjectStateDescriptions数据库表中的查询填充。在这种情况下,_context.ProjectStateDescriptions是IEnumerable<ProjectStateDescription>从查询返回的。ProjectStateCode是表中的主键,表示ViewData字典中的键。StateDescription成为ViewData字典中的关联值。ViewData将用来填充在CustomerProjectCreate.cshtml(见下文)中的<select>元素。ProjectState.Prospect是为<select>从ProjectState enum中默认选择的值。您可以阅读更多ViewData信息在以下链接上 https://www.tektutorialshub.com/viewbag-viewdata-asp-net-core/。(译者注:需要在ProjectStateDescriptions数据库表中手动加入数据,具体可见下图展示的数据加,ProjectStateCode字段的值就是对应枚举中的值--定义在代码中的名称。如此值为Completed,StateDescription字段值为project is complete,以此类推)

初始化~Pages\ Customers\CustomerProjectCreate.cshtml

  1.  
    @page
  2.  
    @model QuantumWeb.Pages.Customers.CustomerProjectCreateModel
  3.  
    @{
  4.  
    ViewData["Title"] = "Create Customer Project";
  5.  
    }
  6.  
     
  7.  
    <h2>Create Customer Project</h2>
  8.  
    <hr />
  9.  
    <dl class="dl-horizontal">
  10.  
    <dt>
  11.  
    @Html.DisplayNameFor(model => model.Customer.CustomerId)
  12.  
    </dt>
  13.  
    <dd>
  14.  
    @Html.DisplayFor(model => model.Customer.CustomerId)
  15.  
    </dd>
  16.  
    <dt>
  17.  
    @Html.DisplayNameFor(model => model.Customer.CustomerName)
  18.  
    </dt>
  19.  
    <dd>
  20.  
    @Html.DisplayFor(model => model.Customer.CustomerName)
  21.  
    </dd>
  22.  
    </dl>
  23.  
    <div class="row">
  24.  
    <div class="col-md-4">
  25.  
    <form method="post">
  26.  
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  27.  
    <input type="hidden" asp-for="Customer.CustomerId" />
  28.  
    <div class="form-group">
  29.  
    <label asp-for="Project.ProjectName" class="control-label"></label>
  30.  
    <input asp-for="Project.ProjectName" class="form-control">
  31.  
    </div>
  32.  
    <div class="form-group">
  33.  
    <label asp-for="Project.ProjectStateCode" class="control-label"></label>
  34.  
    <select asp-for="Project.ProjectStateCode" class="form-control"
  35.  
     
  36.  
    asp-items="ViewBag.ProjectStateCode">
  37.  
    </select>
  38.  
    </div>
  39.  
    <div class="form-group">
  40.  
    <input type="submit" value="Create" class="btn btn-default" />
  41.  
    </div>
  42.  
    </form>
  43.  
    </div>
  44.  
    </div>
  45.  
     
  46.  
    <div>
  47.  
    <a asp-page="CustomerProjects" asp-route-id="@Model.Customer.CustomerId">
  48.  
    Back to Customer Projects
  49.  
    </a>
  50.  
    </div>
  51.  
     
  52.  
    @section Scripts {
  53.  
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
  54.  
    }

关键要素如下:

<input type="hidden" asp-for="Customer.CustomerId" />

这个隐藏<input>捕获目标CustomerId以便在<form>发布时可用它来创建Project。

  1.  
    <select asp-for="Project.ProjectStateCode" class="form-control"
  2.  
    asp-items="ViewBag.ProjectStateCode">
  3.  
    </select>

此<select>元素将显示为UI中的下拉列表,其中包含CustomerProjectCreate.OnGet()方法中ViewData填充的值。

初始化 ~Pages\Customers\CustomerProjectCreate.cshtml

这将显示最初显示的Customers/CustomerProjectCreate页面。

CustomerProjectCreate 包含数据的页面:

点击“ Create”后,我们会看到:

客户Projects页面添加Project:

接下来的两个图显示了为两个Customers添加其他Projects之后的情况。

客户项目页面包含Mirarex Oil&Gas的2个项目:

客户项目页面包含Polyolefin Processing, Inc.的3个项目

我们现在可以添加另一个页面来编辑Customer项目,CustomerProjectEdit页面。

搭建 Customers/CustomerProjectEdit Razor Page

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

  1.  
    using System.Threading.Tasks;
  2.  
    using Microsoft.AspNetCore.Mvc;
  3.  
    using Microsoft.AspNetCore.Mvc.RazorPages;
  4.  
    using Microsoft.AspNetCore.Mvc.Rendering;
  5.  
    using Microsoft.EntityFrameworkCore;
  6.  
    using QuantumWeb.Data;
  7.  
    using QuantumWeb.Model;
  8.  
     
  9.  
    namespace QuantumApp.Pages.Customers
  10.  
    {
  11.  
    public class CustomerProjectEditModel : PageModel
  12.  
    {
  13.  
    private readonly QuantumDbContext _context;
  14.  
     
  15.  
    public CustomerProjectEditModel(QuantumDbContext context)
  16.  
    {
  17.  
    _context = context;
  18.  
    } // end public CustomerProjectEditModel(QuantumDbContext context)
  19.  
     
  20.  
    [BindProperty]
  21.  
    public Customer Customer { get; set; }
  22.  
    [BindProperty]
  23.  
    public Project Project { get; set; }
  24.  
     
  25.  
    public async Task<IActionResult> OnGet(int? id)
  26.  
    {
  27.  
    if (id == null)
  28.  
    {
  29.  
    return NotFound();
  30.  
    } // endif (id == null)
  31.  
     
  32.  
    Project = await _context.Projects
  33.  
    .Include(p => p.Customer)
  34.  
    .FirstOrDefaultAsync(p => p.ProjectId == id);
  35.  
     
  36.  
    if (Project == null)
  37.  
    {
  38.  
    return NotFound();
  39.  
    } // endif (Project == null)
  40.  
     
  41.  
    Customer = Project.Customer;
  42.  
     
  43.  
    ViewData["ProjectStateCode"] = new SelectList(_context.ProjectStateDescriptions,
  44.  
    "ProjectStateCode", "StateDescription", ProjectState.Prospect);
  45.  
     
  46.  
    return Page();
  47.  
    } // end public async Task<IActionResult> OnGet(int? id)
  48.  
     
  49.  
    public async Task<IActionResult> OnPostAsync(int? id)
  50.  
    {
  51.  
    if (!ModelState.IsValid)
  52.  
    {
  53.  
    return Page();
  54.  
    } // endif (!ModelState.IsValid)
  55.  
     
  56.  
    var projectToUpdate = await _context.Projects.FindAsync(id);
  57.  
     
  58.  
    if (projectToUpdate == null)
  59.  
    {
  60.  
    return NotFound();
  61.  
    } // endif (projectToUpdate == null)
  62.  
     
  63.  
    projectToUpdate.CustomerId = Customer.CustomerId;
  64.  
     
  65.  
    if (await TryUpdateModelAsync<Project>(
  66.  
    projectToUpdate,
  67.  
    "project",
  68.  
    p => p.ProjectName, p => p.ProjectStateCode))
  69.  
    {
  70.  
    await _context.SaveChangesAsync();
  71.  
    return RedirectToPage("./CustomerProjects", new { id = Customer.CustomerId });
  72.  
    }
  73.  
     
  74.  
    return Page();
  75.  
    } // end public async Task<IActionResult> OnPostAsync(int? id)
  76.  
     
  77.  
    } // end public class CustomerProjectEditModel : PageModel
  78.  
     
  79.  
    } // end namespace QuantumApp.Pages.Customers

此代码与CustomerProjectCreate页面在.Include和ViewData方面具有相同的构件。

初始化~Pages\Customers\CustomerProjectEdit.cshtml

  1.  
    @page "{id:int?}"
  2.  
    @model QuantumWeb.Pages.Customers.CustomerProjectEditModel
  3.  
    @{
  4.  
    ViewData["Title"] = "Edit Customer Project";
  5.  
    }
  6.  
     
  7.  
    <h2>Edit Customer Project</h2>
  8.  
    <hr />
  9.  
    <dl class="dl-horizontal">
  10.  
    <dt>
  11.  
    @Html.DisplayNameFor(model => model.Customer.CustomerId)
  12.  
    </dt>
  13.  
    <dd>
  14.  
    @Html.DisplayFor(model => model.Customer.CustomerId)
  15.  
    </dd>
  16.  
    <dt>
  17.  
    @Html.DisplayNameFor(model => model.Customer.CustomerName)
  18.  
    </dt>
  19.  
    <dd>
  20.  
    @Html.DisplayFor(model => model.Customer.CustomerName)
  21.  
    </dd>
  22.  
    </dl>
  23.  
    <div class="row">
  24.  
    <div class="col-md-4">
  25.  
    <form method="post">
  26.  
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
  27.  
    <input type="hidden" asp-for="Customer.CustomerId" />
  28.  
    <div class="form-group">
  29.  
    <label asp-for="Project.ProjectName" class="control-label"></label>
  30.  
    <input asp-for="Project.ProjectName" class="form-control">
  31.  
    </div>
  32.  
    <div class="form-group">
  33.  
    <label asp-for="Project.ProjectStateCode" class="control-label"></label>
  34.  
    <select asp-for="Project.ProjectStateCode" class="form-control"
  35.  
     
  36.  
    asp-items="ViewBag.ProjectStateCode">
  37.  
    </select>
  38.  
    </div>
  39.  
    <div class="form-group">
  40.  
    <input type="submit" value="Save" class="btn btn-default" />
  41.  
    </div>
  42.  
    </form>
  43.  
    </div>
  44.  
    </div>
  45.  
     
  46.  
    <div>
  47.  
    <a asp-page="CustomerProjects" asp-route-id="@Model.Customer.CustomerId">
  48.  
    Back to Customer Projects
  49.  
    </a>
  50.  
    </div>
  51.  
     
  52.  
    @section Scripts {
  53.  
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
  54.  
    }

关于CustomerId的隐藏<input>和<select>,此页面具有与CustomerProjectCreate页面相同的元素。

Customer Projects 页面包含Mirarex Oil&Gas的2个项目——用于编辑:

Mirarex Oil&Gas, Zolar Pipeline的客户项目编辑页面:

客户项目页面包含Mirarex Oil & Gas 的2个项目——项目编辑:

通过CustomerProjectDelete页面,此项目的最后一个功能是删除。

搭建 Customers/CustomerProjectDelete Razor页面:

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

  1.  
    using System.Threading.Tasks;
  2.  
    using Microsoft.AspNetCore.Mvc;
  3.  
    using Microsoft.AspNetCore.Mvc.RazorPages;
  4.  
    using Microsoft.EntityFrameworkCore;
  5.  
    using QuantumWeb.Data;
  6.  
    using QuantumWeb.Model;
  7.  
     
  8.  
    namespace QuantumWeb.Pages.Customers
  9.  
    {
  10.  
    public class CustomerProjectDeleteModel : PageModel
  11.  
    {
  12.  
    private readonly QuantumDbContext _context;
  13.  
     
  14.  
    public CustomerProjectDeleteModel(QuantumDbContext context)
  15.  
    {
  16.  
    _context = context;
  17.  
    } // end public CustomerProjectDeleteModel(QuantumContext context)
  18.  
     
  19.  
    [BindProperty]
  20.  
    public Customer Customer { get; set; }
  21.  
    [BindProperty]
  22.  
    public Project Project { get; set; }
  23.  
     
  24.  
    public async Task<IActionResult> OnGetAsync(int? id)
  25.  
    {
  26.  
    if (id == null)
  27.  
    {
  28.  
    return NotFound();
  29.  
    } // endif (id == null)
  30.  
     
  31.  
    Project = await _context.Projects
  32.  
    .Include(p => p.Customer)
  33.  
    .FirstOrDefaultAsync(p => p.ProjectId == id);
  34.  
     
  35.  
    if (Project == null)
  36.  
    {
  37.  
    return NotFound();
  38.  
    } // endif (Project == null)
  39.  
     
  40.  
    Customer = Project.Customer;
  41.  
     
  42.  
    return Page();
  43.  
    } // end public async Task<IActionResult> OnGet(int? id)
  44.  
     
  45.  
    public async Task<IActionResult> OnPostAsync(int? id)
  46.  
    {
  47.  
    if (id == null)
  48.  
    {
  49.  
    return NotFound();
  50.  
    } // endif (id == null)
  51.  
     
  52.  
    Project = await _context.Projects
  53.  
    .Include(p => p.Customer)
  54.  
    .FirstOrDefaultAsync(p => p.ProjectId == id);
  55.  
     
  56.  
    if (Project != null)
  57.  
    {
  58.  
    _context.Projects.Remove(Project);
  59.  
    await _context.SaveChangesAsync();
  60.  
    } // endif (Project != null)
  61.  
     
  62.  
    return RedirectToPage("./CustomerProjects", new { id = Project.Customer.CustomerId });
  63.  
    } // end public async Task<IActionResult> OnPostAsync(int? id)
  64.  
     
  65.  
    } // end public class CustomerProjectDeleteModel : PageModel
  66.  
     
  67.  
    } // end namespace QuantumWeb.Pages.Customer

初始化~Pages\Customers\CustomerProjectDelete.cshtml

  1.  
    @page "{id:int?}"
  2.  
    @model QuantumWeb.Pages.Customers.CustomerProjectDeleteModel
  3.  
    @{
  4.  
    ViewData["Title"] = "Delete Customer Project";
  5.  
    }
  6.  
     
  7.  
    <h2>Delete Customer Project</h2>
  8.  
     
  9.  
    <h3>Are you sure you want to delete this?</h3>
  10.  
    <div>
  11.  
    <dl class="dl-horizontal">
  12.  
    <dt>
  13.  
    @Html.DisplayNameFor(model => model.Customer.CustomerName)
  14.  
    </dt>
  15.  
    <dd>
  16.  
    @Html.DisplayFor(model => model.Customer.CustomerName)
  17.  
    </dd>
  18.  
    <dt>
  19.  
    @Html.DisplayNameFor(model => model.Project.ProjectId)
  20.  
    </dt>
  21.  
    <dd>
  22.  
    @Html.DisplayFor(model => model.Project.ProjectId)
  23.  
    </dd>
  24.  
    <dt>
  25.  
    @Html.DisplayNameFor(model => model.Project.ProjectName)
  26.  
    </dt>
  27.  
    <dd>
  28.  
    @Html.DisplayFor(model => model.Project.ProjectName)
  29.  
    </dd>
  30.  
    <dt>
  31.  
    @Html.DisplayNameFor(model => model.Project.ProjectStateCode)
  32.  
    </dt>
  33.  
    <dd>
  34.  
    @Html.DisplayFor(model => model.Project.ProjectStateCode)
  35.  
    </dd>
  36.  
    </dl>
  37.  
     
  38.  
    <form method="post">
  39.  
    <input type="hidden" asp-for="Project.ProjectId" />
  40.  
    <a asp-page="CustomerProjects" asp-route-id="@Model.Customer.CustomerId">
  41.  
    Back to Customer Projects
  42.  
    </a> |
  43.  
    <input type="submit" value="Delete" class="btn btn-default" />
  44.  
    </form>
  45.  
    </div>

客户项目页面包含Mirarex Oil & Gas的3个项目:

删除客户项目页面——删除Ouachita Shale:

客户项目页面包含Mirarex Oil&Gas的2个项目:

此时,我们可以总结下表中的测试数据:

Customers, Projects, ProjectStates

CustomerId

Customer Name

ProjectId

Project Name

ProjectStateCode

StateDescription

1

Mirarex Oil & Gas, LLC

1

Zolar Pipeline

UnderReview

Project is under review and negotiation

1

Mirarex Oil & Gas, LLC

2

Nelar Ranch Gas Fracturing

Prospect

Prospective or referred project

2

Polyolefin Processing, Inc.

3

Port Gibson Plant Expansion

Prospect

Prospective or referred project

2

Polyolefin Processing, Inc.

4

Jackson Plant Control System Upgrade

Prospect

Prospective or referred project

2

Polyolefin Processing, Inc.

5

Eutaw Plant Shutdown & Maintenance

Prospect

Prospective or referred project

下面可以进入第四部分进行学习。

https://blog.csdn.net/mzl87/article/details/85312583

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

使用EntityFramework Core和Enums作为字符串的ASP.NET Core Razor页面——第三部分的更多相关文章

  1. C# 6 与 .NET Core 1.0 高级编程 - 40 ASP.NET Core(上)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 40 章  ASP.NET Core(上)),不对的地方欢迎指出与交流. 章节出自<Professiona ...

  2. C# 6 与 .NET Core 1.0 高级编程 - 40 ASP.NET Core(下)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 40 章  ASP.NET Core(下)),不对的地方欢迎指出与交流. 章节出自<Professiona ...

  3. Asp.net Core 1.0.1升级到Asp.net Core 1.1.0 Preview版本发布到Windows Server2008 R2 IIS中的各种坑

    Asp.net Core 1.0.1升级到Asp.net Core 1.1.0后,程序无法运行了 解决方案:在project.json中加入runtime节点 "runtimes" ...

  4. ASP.NET Core 入门教程 1、使用ASP.NET Core 构建第一个Web应用

    一.前言 1.本文主要内容 Visual Studio Code 开发环境配置 使用 ASP.NET Core 构建Web应用 ASP.NET Core Web 应用启动类说明 ASP.NET Cor ...

  5. ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 使用 EF 框架查询数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 使用 EF 框架查询数据 上一章节我们学习了如何设置 ...

  6. 基于 Vue.js 之 iView UI 框架非工程化实践记要 使用 Newtonsoft.Json 操作 JSON 字符串 基于.net core实现项目自动编译、并生成nuget包 webpack + vue 在dev和production模式下的小小区别 这样入门asp.net core 之 静态文件 这样入门asp.net core,如何

    基于 Vue.js 之 iView UI 框架非工程化实践记要   像我们平日里做惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还常常停留在 jQuery 时代,包括其插件在需要时就引 ...

  7. ASP.NET CORE系列【一】搭建ASP.NET CORE项目

    为什么要使用 ASP.NET Core? NET Core 刚发布的时候根据介绍就有点心里痒痒,微软的尿性都懂的,新东西bug太多,现在2.0也发布很久了,决定研究一下. ASP.NET Core官方 ...

  8. ASP.NET Core 入门教程 2、使用ASP.NET Core MVC框架构建Web应用

    一.前言 1.本文主要内容 使用dotnet cli创建基于解决方案(sln+csproj)的项目 使用Visual Studio Code开发基于解决方案(sln+csproj)的项目 Visual ...

  9. 【转】asp.net Core 系列【二】—— 使用 ASP.NET Core 和 VS2017 for Windows 创建 Web API

    在本教程中,将生成用于管理“待办事项”列表的 Web API. 不会生成 UI. 概述 以下是将创建的 API: API 描述 请求正文 响应正文 GET /api/todo 获取所有待办事项 无 待 ...

  10. Asp.Net Core 学习教程2、使用ASP.NET Core中的RazorPages

    1.创建一个Asp.Net Core Web应用程序 1.1.打开VS2019 新建项目 1.2.选好项目位置后进入线面界面,选择Web应用程序 1.3.进去的页面结构如下 Pages 文件夹:包含 ...

随机推荐

  1. Perm 排列计数——Lucas&dfs

    思路:这道题给出的公式看明白后即可得出正解,我们可以把他想象成一颗二叉树,任意一个点的任意一个子孙一直除以2后最终都会到达一终点,终点则为以该点为根的子树的最小值. so--我们可以将根节点作为最后终 ...

  2. 英文A+B

    A+B 题目描述 读入两个小于100的正整数A和B,计算A+B. 需要注意的是:A和B的每一位数字由对应的英文单词给出. 输入描述: 测试输入包含若干测试用例,每个测试用例占一行,格式为"A ...

  3. Mac 上fiddler与charles 抓包https 小程序请求 内容

    为什么选择charles 之前讲过<wireshark使用教程及过滤语法总结--血泪史的汇聚>, 很强大,但是很难用. fiddler 很好用,之前mac 上面没有,现在有了 fiddle ...

  4. 饿了么EMonitor演进史

    简介: 可观测性作为技术体系的核心环节之一,跟随饿了么技术的飞速发展,不断自我革新. 序言 时间回到2008年,还在上海交通大学上学的张旭豪.康嘉等人在上海创办了饿了么,从校园外卖场景出发,饿了么一步 ...

  5. 2018-7-15-WPF-在-DrawingContext-的-push-如何使用

    title author date CreateTime categories WPF 在 DrawingContext 的 push 如何使用 lindexi 2018-7-15 15:51:0 + ...

  6. QT 连接 MySQL 版本问题

    问题现象 SSL connection error: unknown error number QMYSQL: Unable to connect 问题原因 出现这样的现象是因为我QT使用的是5.7的 ...

  7. 史上功能最全的Java权限认证框架!

    大家好,我是 Java 陈序员.权限认证是我们日常开发绕不过的话题,这是因为我们的应用程序需要防护,防止被窜入和攻击. 在 Java 后端开发中,实现权限认证有很多种方案可以选择,一个拦截器.过滤器也 ...

  8. Django Admin后台管理:高效开发与实践

    title: Django Admin后台管理:高效开发与实践 date: 2024/5/8 14:24:15 updated: 2024/5/8 14:24:15 categories: 后端开发 ...

  9. 06 curl 操作elasticsearch的CRUD

    目录 查看健康状态 查询当前es集群中所有的indices 创建索引并配置: 创建索引 删除索引 获取mapping 创建mapping 添加字段 插入记录 检索 修改 删除 中文文档: https: ...

  10. CSS自适应网页(CSS第一篇)

    ​CSS的属性: 用浏览器自带的审查元素对一些页面进行调整,快捷键是F12. 网页允许宽度自适应: 在代码的头部加入一行viewport元标签. <meta name="viewpor ...