Microsoft Blazor Platz.SqlForms开源-使用架构生成器设计和维护SQL Server数据库

当您需要为客户构建有效的原型或公司没有用于企业发展的预算时,您别无选择,并且需要使用一些捷径和生活技巧,通常是低代码或无代码方法。在这篇文章中,我提出了一种有趣的方法,它关于如何使用开源库Platz.SqlForms快速开发BlazorUI。SqlForms将提供SPA用户体验,并且无需您进行任何编码即可与数据库进行通信,您所要做的就是定义提供流畅符号定义的UI表单。使用嵌入式数据库架构设计器,可以定义要显示为UI控件的实体。

创建演示项目

使用VisualStudio,单击“创建新项目”,然后找到BlazorServerApp。

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

VisualStudio应该为您创建一个新项目:

添加Platz包

下一步是添加NuGet软件包-右键单击项目,然后单击菜单项“ManageNuGetPackages…”。

选择“浏览”标签,然后在搜索框中输入“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();
}123456789复制代码类型:[html]

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

如何使用Platz对象构建器

PlatzSchemaDesigner和QueryBuilder是我们添加的无代码元素,用于简化和加快开发过程。

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

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

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

设置Platz无代码生成器

要设置无代码生成器,我们需要创建两个剃刀页面并将它们注册到Shared\NavMenu.razor中,还可以删除VisualStudio演示页面(Counter.razor和FetchData.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" />1234567复制代码类型:[html]

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

@page "/QueryDesigner"
@using Platz.ObjectBuilder<QueryComponent SourceSchemaFile="SchemaStore\PlatzDemo.schema.json"
 StoreDataPath="SchemaStore"
 DataService="PlatzDemoDataContext" Namespace="PlatzDemo.SchemaStore" />123456复制代码类型:[html]

将指向JQuery的链接添加到'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/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
  integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
  crossorigin="anonymous">
 <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
  integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
  crossorigin="anonymous"></script>
 <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
  integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
  crossorigin="anonymous"></script>
 <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js"
  integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s"
  crossorigin="anonymous"></script>

 <link href="css/site.css" rel="stylesheet" />
 <link href="Platz.SqlForms.Demo.styles.css" rel="stylesheet" /></head>...12345678910111213141516171819202122232425262728复制代码类型:[html]

并更改“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>...123456789101112131415161718192021复制代码类型:[html]

设计演示数据库

现在,让我们运行该应用程序,然后单击“管理模式”页面。您将看到带有新架构的页面,该页面已可以创建。

输入“PlatzDemo”作为架构名称,然后选择“使用INT自动增量ID”选项。现在,您可以通过单击绿色的“添加”按钮来添加表。

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

对于每一列,您应该指定Name和Type。

我创建了一个'Product'表:

现在,我想再添加两个表来创建客户订单输入系统,您可以在图上看到添加的表。添加所有表后,单击“模式”选项卡上的“保存”按钮。

可以看到,我从'OrderItem'表中添加了对Order'和'Product的引用。

建立查询

保存架构后,我们可以单击“管理查询”菜单,然后使用定义的表来构建查询。

在下面的屏幕中,您可以看到已设计的表已合并以产生订单项列表页面所需的输出。

当你关闭浏览器,你应该看到的是,项目文件夹“SchemaStore”现在包含文件:“GetOrderItemProductList.json”与查询定义,“PlatzDemo.schema.json”和“PlatzDemo.schema.migrations.json”以及架构定义。

生成数据上下文代码

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

<# // ================================================================
Set JsonStorePath here, relative to solution folder ================================== #>
<#   string JsonStorePath = @"Platz.SqlForms.Demo\SchemaStore\PlatzDemo.schema.json"; #>
<# // =========================================================================
============================================================================== #>12345复制代码类型:[html]

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

// *********************************************************************************************
// 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
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758复制代码类型:[html]

为了能够使用生成的代码,我们只需要将连接字符串添加到“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": "*"
}1234567891011121314复制代码类型:[html]

如您所见,我在此演示中使用了MicrosoftSQLLocalDB。

创建动态表单

我们创建一个“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;
  }
 }
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051复制代码类型:[html]

现在,我们添加Blazor页面以呈现产品表单,并在'NavMenu.razor'中注册产品列表页面。

产品清单剃刀

@page "/ProductList/"
@using Platz.SqlForms.Demo.SchemaForms<h1>Product Edit</h1><FormDataServiceListComponent TForm="ProductListForm" />123456复制代码类型:[html]

产品编辑器

@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; }
}1234567891011复制代码类型:[html]

产品删除剃刀

@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; }
}1234567891011复制代码类型:[html]

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

我们省略了此代码以减少阅读时间。您可以在GitHub上找到完整的代码。

测试应用

当我们第一次启动该应用程序时,它将自动创建SQL数据库并应用所有迁移脚本。

您将能够在Platz.SqlForms项目文档中找到有关如何使用迁移的详细信息,该迁移将在更接近最终发行日期的地方进行。

您现在可以将新产品添加到数据库中,进行编辑和删除。

完整的项目演示还包含用于添加和编辑Orders和OrderItems的功能。

结论

在本文中,我们演示了如何使用嵌入式模式设计器定义数据库并将其用于动态UI生成。

模式设计器和查询构建器为Platz.SqlForms快速开发和原型添加了无代码技术。我们知道从维护的角度来看,无代码可能会很痛苦,因此这就是我们提出一种新方法的原因-将您的模式或查询设计保存到json,然后您可以使用许多t4模板来生成结果代码。

未来的发行版可能包含生成EntityFramework数据上下文的t4模板,因此从无代码原型开始的开发人员将能够迁移到可靠的MicrosoftORM。

(0)

相关推荐