目录

介绍

使用代码


添加项目和项目状态处理

介绍

这是一篇由多部分组成的文章的第三部分,演示了通过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. 动态规划(五)——坐标dp

    传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵, 而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了 ...

  2. UML 哲学之道——领域模型[四]

    前言 简单整理一下领域模型. 正文 领域模型是对领域内的概念类或现实中的对象的可视化表示 领域模型也称概念模型.领域对象模型和分析对象模型 领域模型是可以在业务建模科目中创建的制品之一 领域模型是up ...

  3. MVC 测试action的运行速度

    前言 网络很多文章有关于action的测试机制,本文主要是整理一下思路. 正文 假如有一个acion: public ActionResult Index() { return View(); } 当 ...

  4. 利用navicat实现excel转json

    1.需要工具,Navicat Premium,网上有破解及安装教程 2.新建sqlite连接,选择新建sqlite3,如下图 3.接着点确定,如图 4. 5.

  5. 自动化部署脚本--一键部署单机版k8s

    cat danjiDeploy_k8s.sh #!/bin/bash . /etc/init.d/functions # 版本 VERSION=v1.0.1 # IP地址,默认为本机第一块网卡IP地址 ...

  6. JavaWeb技术JSP连接数据库操作

    "感谢您阅读本篇博客!如果您觉得本文对您有所帮助或启发,请不吝点赞和分享给更多的朋友.您的支持是我持续创作的动力,也欢迎留言交流,让我们一起探讨技术,共同成长!谢谢!" 0X01 ...

  7. JVM简明笔记4:垃圾回收

    1 垃圾回收相关算法 垃圾回收器首先要做的就是,判断一个对象是存活状态还是死亡状态,死亡的对象将会被标识为垃圾数据并等待收集器进行清除. 判断一个对象是否为死亡状态的常用算法有两个:引用计数器算法 . ...

  8. 【数学】主成分分析(PCA)的详细深度推导过程

    Based on Deep Learning (2017, MIT) book. 本文基于Deep Learning (2017, MIT),推导过程补全了所涉及的知识及书中推导过程中跳跃和省略的部分 ...

  9. 力扣191(java)-位1的个数(简单)

    题目: 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量). 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型. ...

  10. 开源自建/托管与商业化自研 Trace,如何选择?

    ​简介: 随着微服务架构的兴起,服务端的调用依赖愈加复杂,为了快速定位异常组件与性能瓶颈,接入分布式链路追踪 Trace 已经成为 IT 运维领域的共识.但是,开源自建.开源托管或商业化自研 Trac ...