目录

介绍

使用代码


添加项目和项目状态处理

介绍

这是一篇由多部分组成的文章的第三部分,演示了通过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. Luogu P3007 奶牛议会

    观前须知 本题解使用 CC BY-NC-SA 4.0 许可. 同步发布于 Luogu 题解区. 更好的观看体验 请点这里. 笔者的博客主页 正文 Luogu P3007 [USACO11JAN] Th ...

  2. 【cef编译包】下载地址

    http://opensource.spotify.com/cefbuilds/index.html

  3. Oracle 将字符中含有的字母或特殊字符去除并将字符串置换成数字

    将字符中含有的字母或特殊字符去除并将字符串置换成数字 将字符中含有的字母或特殊字符去除并将字符串置换成数字 to_number(nvl(TRANSLATE(u.scsqrbzl, 'qwertyuio ...

  4. 龙蜥开源内核追踪利器 Surftrace:协议包解析效率提升 10 倍! | 龙蜥技术

    ​简介:如何将网络报文与内核协议栈清晰关联起来精准追踪到关注的报文行进路径呢? ​ 文/系统运维 SIG Surftrace 是由系统运维 SIG 推出的一个 ftrace 封装器和开发编译平台,让用 ...

  5. 阿里云张献涛:自主最强DPU神龙的秘诀

    ​简介:读懂云计算,才能看清DPU热潮. 微信公众号搜索"弹性计算百晓生",获取更多云计算知识. 如果细数最近火爆的科技概念,DPU必然位列其中. 这是英伟达一手捧红的新造富故事, ...

  6. 阿里云AHAS Chaos:应用及业务高可用提升工具平台之故障演练

    简介: 阿里云AHAS Chaos:应用及业务高可用提升工具平台之故障演练 应用高可用服务AHAS及故障演练AHAS Chaos 应用高可用服务(Application High Availabili ...

  7. 友盟+U-APM 移动应用性能体验报告:Android崩溃率达0.32%,OPPO 、华为、VIVO 崩溃表现良好

    简介: 应用性能稳定是良好用户体验中非常关键的一环,而现实情况却是应用崩溃.卡顿.加载缓慢.页面白屏等问题,频频出现在用户的真实体验之中,成为影响业务表现的直接杀手.为此,应用性能管理(APM)正在国 ...

  8. Forrester云原生开发者洞察白皮书,低代码概念缔造者又提出新的开发范式

    简介: 云原生时代的到来为开发者群体带来了前所未有的机遇,让开发者可以更加专注业务价值创造与创新,并使得人人成为开发者成为现实.广大开发者如何转型成为云原生开发者?运维等专业人员在云原生时代如何避免边 ...

  9. [Py] Python 的 shape、reshape 含义与用法

    shape 方法用于查看数据是几行几列的. reshape 方法用于不更改数据的情况下,重新把数据进行规划成指定的行数和列数. .reshape(-1, 1)  -1 表示自动,1 表示整理成 1 列 ...

  10. win10 uwp 简单制作一个 Path 路径绘制的图标按钮

    本文告诉大家在 UWP 或 WinUI 3 里面如何简单制作一个由 Path 几何路径图形绘制的图标按钮 先在资源里面定义按钮的样式,重写 Template 属性,通过在 Template 里面放入 ...