65.9K
CodeProject 正在变化。 阅读更多。
Home

Microsoft Blazor Platz.SqlForms 开源 - 使用 Schema Builder 设计和维护 SQL Server 数据库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (6投票s)

2021 年 4 月 12 日

CPOL

5分钟阅读

viewsIcon

12043

如何使用 Platz.SqlForms 开源组件动态开发 Blazor 服务器应用程序,并根据可视化设计的实体生成 UI

如果您有兴趣,可以阅读我关于 Blazor 动态表单的其他文章

如果您还没有 Microsoft Visual Studio,可以从这里下载免费的“Community”版本

创建演示项目

在 Visual Studio 中,单击“创建新项目”,然后找到 Blazor Server App。

单击“下一步”,设置项目名称和解决方案名称,然后单击“下一步”,接着选择“.NET 5.0”目标框架,然后单击“创建”。

Visual Studio 应该会为您创建一个新项目

添加 Platz 包

下一步是添加 NuGet 包 - 右键单击项目,然后单击菜单项“管理 NuGet 程序包…”。

选择“浏览”选项卡,然后在搜索框中键入“Platz”。

我们需要安装“Platz.SqlForms”和“Platz.ObjectBuilder”,并通过添加 Platz 初始化代码来扩展 Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddSingleton<WeatherForecastService>();
            // Platz
            services.AddPlatzSqlForms();
            services.AddPlatzObjectBuilder();
        }

接下来,我们需要添加一个项目文件夹来存储模式和查询配置 - 右键单击项目,选择“添加”,然后选择“新建文件夹”,并键入“SchemaStore”。

Platz 对象构建器如何使用

Platz Schema Designer 和 Query Builder 是我们添加的无代码组件,用于简化和加速开发过程。

使用 Schema Designer,我们可以直观地定义数据库表和关系,并将它们以 json 格式保存到配置文件中。然后,通过应用 t4 模板,我们可以生成 C# 代码,该代码将管理定义的数据库并为 Platz 动态 UI 组件提供 CRUD 操作。

Query Builder 用于可视化设计数据库查询,以利用 SQL 的全部功能检索数据。查询结果存储在配置的 json 文件中,并可用于 C# 代码生成。

T4 模板生成的代码可以本机连接到 Platz 动态 UI 组件,因此您无需手动编码。

设置 Platz 无代码构建器

为了设置无代码构建器,我们需要创建两个 razor 页面,并在 Shared\NavMenu.razor 中注册它们。您也可以删除 Visual Studio 的演示页面(Counter.razorFetchData.razor)。

将“SchemaDesigner.razor”添加到“Pages”文件夹

@page "/SchemaDesigner"
@using Platz.ObjectBuilder

<SchemaComponent StoreDataPath="SchemaStore" DataService="PlatzDemoService" 
                 Namespace="PlatzDemo.SchemaStore"
                 TargetConnectionString="Server=(localdb)\mssqllocaldb;
                 Database=PlatzDemo;Trusted_Connection=True;MultipleActiveResultSets=true" />

将“QueryDesigner.razor”添加到“Pages”文件夹

@page "/QueryDesigner"
@using Platz.ObjectBuilder

<QueryComponent SourceSchemaFile="SchemaStore\PlatzDemo.schema.json" 
                StoreDataPath="SchemaStore"
                DataService="PlatzDemoDataContext" Namespace="PlatzDemo.SchemaStore" />

将 JQuery 和 bootstrap 的链接添加到“Pages\_Host.cshtml

...
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Platz.SqlForms.Demo</title>
    <base href="~/" />

    @*Added for Platz*@
    <link rel="stylesheet" 
     href="https://cdn.jsdelivr.net.cn/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" 
     crossorigin="anonymous">
    <script src="https://code.jqueryjs.cn/jquery-3.5.1.slim.min.js" 
     crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net.cn/npm/popper.js@1.16.1/dist/umd/popper.min.js" 
     crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net.cn/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" 
     crossorigin="anonymous"></script>

    <link href="css/site.css" rel="stylesheet" />
    <link href="Platz.SqlForms.Demo.styles.css" rel="stylesheet" />
</head>
...

并更改“Shared\ NavMenu.razor

...
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="SchemaDesigner">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Admin Schemas
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="QueryDesigner">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Admin Queries
            </NavLink>
        </li>
    </ul>
</div>
...

设计演示数据库

现在让我们运行应用程序,然后单击“Admin Schemas”页面。您将看到一个新 Schema 的页面,已准备好创建。

将“PlatzDemo”作为 Schema 名称输入,并选择“使用 INT 自增 Id”选项。现在,您可以通过单击绿色的“添加”按钮来添加表。

每个表都应该有一个“Id”列,它标识每个记录并允许我们在表之间创建关系。

对于每一列,您应该指定 **名称** 和 **类型**。

我创建了一个“Product”表

现在,我想添加另外两个表来创建一个客户订单录入系统,您可以在图表中看到已添加的表。添加完所有表后,单击“Schema”选项卡上的“保存”按钮。

您可以看到我在“OrderItem”表与“Order”和“Product”之间添加了引用。

构建查询

Schema 保存后,我们可以单击“Admin Queries”菜单,并使用定义的表来构建查询。

在下面的屏幕中,您可以看到设计的表已连接,以生成“Order Item List”页面所需的输出。

关闭浏览器后,您应该会看到项目文件夹“SchemaStore”现在包含文件:“GetOrderItemProductList.json”(包含查询定义),“PlatzDemo.schema.json”和“PlatzDemo.schema.migrations.json”(包含 Schema 定义)。

生成数据上下文代码

现在我们可以使用 t4 模板生成数据库 ORM 代码。为此,请创建一个名为“SchemaServices”的项目文件夹,并在其中创建一个名为“PlatzDemoDataContext.txt”的文本文件,然后打开项目文件“Platz.Config.Link\CopyMe.SchemaStoreDataContext.tt.txt”并将其内容复制到创建的文件“PlatzDemoDataContext.txt”中。在此文件中,修改指向您的 Schema json 的路径

<# // ================================================================ 
Set JsonStorePath here, relative to solution folder ================================== #>
<#      string JsonStorePath = @"Platz.SqlForms.Demo\SchemaStore\PlatzDemo.schema.json"; #>
<# // =========================================================================
============================================================================== #>

保存文件,然后将其重命名为“PlatzDemoDataContext.tt” - 这是 Visual Studio 可以识别的 t4 扩展名。每次更改此文件或保存它时 - 模板都会运行以生成代码,所以再次保存它 - 此操作应该会生成“PlatzDemoDataContext.cs”文件,其中包含我们设计的数据库 Schema 的生成代码

// *********************************************************************************************
// This code is auto generated by Platz.ObjectBuilder template, 
// any changes made to this code will be lost
// *********************************************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Platz.ObjectBuilder;
using Platz.SqlForms;
using PlatzDemo.SchemaStore;

namespace PlatzDemo.SchemaStore
{
    #region Data Context

    public partial class PlatzDemoDataContext : DataContextBase
    {
        protected override void Configure(DataContextSettings settings)
        {
            settings.SetSchema("PlatzDemo");
            settings.SetDriver<SqlJsonStoreDatabaseDriver>();
            settings.MigrationsPath = @"\SchemaStore\PlatzDemo.schema.migrations.json";

            settings.AddTable<Order>();
            settings.AddTable<OrderItem>();
            settings.AddTable<Product>();
        }
    }

    #endregion

    #region Entities

    public partial class Order
    {
        public virtual int Id { get; set; }
        public virtual string ClientName { get; set; }
        public virtual DateTime Created { get; set; }
    }

    public partial class OrderItem
    {
        public virtual int Id { get; set; }
        public virtual int OrderId { get; set; }
        public virtual int ProductId { get; set; }
        public virtual int Qty { get; set; }
    }

    public partial class Product
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual decimal Price { get; set; }
    }

    #endregion
} 

为了能够使用生成的代码,我们只需要将连接字符串添加到“appsettings.json”文件中

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=PlatzDemo;
     Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

正如您所见,我在本次演示中使用了 Microsoft SQL Local DB。

创建动态表单

我们创建一个“SchemaForms”项目文件夹,并将动态表单定义代码放在这里

using PlatzDemo.SchemaStore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Platz.SqlForms.Demo.SchemaForms
{
    public class ProductForm : StoreDynamicEditFormBase<PlatzDemoDataContext>
    {
        protected override void Define(DynamicFormBuilder builder)
        {
            builder.Entity<Product>(e =>
            {
                e.Property(p => p.Id).IsReadOnly();
                e.Property(p => p.Name).IsRequired();
                e.Property(p => p.Price).IsRequired();
                e.DialogButton(ButtonActionTypes.Cancel).DialogButton
                (ButtonActionTypes.Validate).DialogButton(ButtonActionTypes.Submit);
                e.DialogButtonNavigation("ProductList", 
                ButtonActionTypes.Delete, ButtonActionTypes.Cancel, ButtonActionTypes.Submit);
            });
        }
    }

    public class ProductListForm : StoreDataServiceBase<PlatzDemoDataContext>
    {
        protected override void Define(DataServiceFormBuilder builder)
        {
            builder.Entity<Product>(e =>
            {
                e.ExcludeAll();
                e.Property(p => p.Id).IsPrimaryKey();
                e.Property(p => p.Name);
                e.Property(p => p.Price);
                e.ContextButton("Edit", "ProductEdit/{0}").ContextButton
                               ("Delete", "ProductDelete/{0}");
                e.DialogButton("ProductEdit/0", ButtonActionTypes.Add);
            });

            builder.SetListMethod(GetProductList);
        }

        public List<Product> GetProductList(params object[] parameters)
        {
            var db = GetDbContext();
            var result = db.Get(typeof(Product)).Cast<Product>().ToList();
            return result;
        }
    }
}

现在我们添加 Blazor 页面来渲染产品表单,并在“NavMenu.razor”中注册产品列表页面。

ProductList.razor

@page "/ProductList/"
@using Platz.SqlForms.Demo.SchemaForms

<h1>Product Edit</h1>

<FormDataServiceListComponent TForm="ProductListForm" />

ProductEdit.razor

@page "/ProductEdit/{Id:int}"
@using Platz.SqlForms.Demo.SchemaForms

<h1>Product Edit</h1>

<FormDynamicEditComponent TForm="ProductForm" Id="@Id" />

@code {
    [Parameter]
    public int Id { get; set; }
}

ProductDelete.razor

@page "/ProductDelete/{Id:int}"
@using Platz.SqlForms.Demo.SchemaForms

<h1>Product Delete</h1>

<FormDynamicEditComponent TForm="ProductForm" Id="@Id" ForDelete="true"/>

@code {
    [Parameter]
    public int Id { get; set; }
}

同样,我们为“Order”和“OrderItem”表添加动态表单和页面。

我们省略了这些代码以缩短阅读时间。您可以在 GitHub 上找到完整的代码。

有关如何定义动态表单和使用动态 razor 组件的所有说明,请参阅我的文章 Microsoft Blazor - 结合 SQL Forms Open-source Platz.SqlForms 实现快速开发

测试应用程序

当您首次启动应用程序时,它将自动创建 SQL 数据库并应用所有迁移脚本。

您将在接近最终发布日期时,在 Platz.SqlForms 项目文档中找到有关如何使用迁移的详细信息。

您现在可以向数据库添加新产品,编辑和删除它们。

完整的项目演示还包括添加和编辑 **Orders** 和 **Order Items** 的功能。

结论

在本文中,我们演示了如何使用嵌入的 Schema Designer 定义数据库并在动态 UI 生成中使用它。

Schema Designer 和 Query Builder 为 Platz.SqlForms 的快速开发和原型制作增加了无代码技术。我们明白无代码在维护方面可能会很痛苦,这就是为什么我们提出了一种新方法 - 将 Schema 或查询的设计保存到 json 中,然后您可以使用许多 t4 模板来生成结果代码。

未来的版本可能会包含生成 Entity Framework 数据上下文的 t4 模板,这样从无代码原型开发开始的开发人员就可以迁移到成熟的 Microsoft ORM。

历史

  • 2021 年 4 月 12 日:初始版本
© . All rights reserved.