### Multi-Database Transaction Setup Source: https://rightpolice.github.io/Furion-Documentation/docs/sqlsugar Configure and manage transactions across multiple databases using SqlSugarClient. This example shows how to get connections for different databases and execute commands within a transaction block. ```csharp SqlSugarClient db = new SqlSugarClient(new List() { new ConnectionConfig(){ ConfigId="0", DbType=DbType.SqlServer, ConnectionString=Config.ConnectionString, IsAutoCloseConnection=true }, new ConnectionConfig(){ ConfigId="1", DbType=DbType.MySql, ConnectionString=Config.ConnectionString4 ,IsAutoCloseConnection=true} }); var mysqldb = db.GetConnection("1"); // mysql db var sqlServerdb = db.GetConnection("0"); // sqlserver db db.BeginTran(); mysqldb.Insertable(new Order() { CreateTime = DateTime.Now, CustomId = 1, Name = "a", Price = 1 }).ExecuteCommand(); mysqldb.Queryable().ToList(); sqlServerdb.Queryable().ToList(); db.CommitTran(); ``` -------------------------------- ### Grouping Query Examples Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-hight-query Provides examples of grouping data using LINQ. The first example groups by multiple columns, the second groups and counts results, and the third involves joins before grouping. ```csharp // 示例一 var query = repository.AsQueryable().GroupBy(x => new { x.Column1, x.Column2 }); ``` ```csharp // 示例二 var query = from student in repository.AsQueryable() group student by repository2.AsQueryable() into dateGroup select new ResultData() { Key = dateGroup.Key, Value = dateGroup.Count() }; ``` ```csharp // 示例三 var query = from a in repository.AsQueryable() join b in repository2.AsQueryable() on a.Id equals b.Aid join c in repository3.AsQueryable() on c.id equals b.Bid group a by new { a.Age, b.Sex } into g select new { Peo = g.Key, Count = g.Count() }; ``` -------------------------------- ### Install CliWrap Source: https://rightpolice.github.io/Furion-Documentation/docs/dotnet-tools Install the CliWrap NuGet package to enable the execution of local commands from your .NET application. ```bash dotnet add package CliWrap ``` -------------------------------- ### Vue 3 SignalR Client Example Source: https://rightpolice.github.io/Furion-Documentation/docs/signalr This example demonstrates setting up a SignalR connection in a Vue 3 application. It includes initializing the HubConnection, starting the connection, sending a message, and registering a handler for receiving messages from the server. ```typescript import { HubConnectionBuilder } from "@microsoft/signalr"; ``` -------------------------------- ### Install My.Extensions.Localization.Json Package Source: https://rightpolice.github.io/Furion-Documentation/docs/local-language Add the My.Extensions.Localization.Json NuGet package to your project to enable JSON-based localization. ```bash dotnet add package My.Extensions.Localization.Json ``` -------------------------------- ### Minimal API Application Setup with Furion Source: https://rightpolice.github.io/Furion-Documentation/docs/upgrade Shows how to integrate Furion into a Minimal API application by registering services with AddInjectMini() and using UseInject(). ```csharp var builder = WebApplication.CreateBuilder(args).Inject(); // Register Minimal services builder.Services.AddInjectMini(); var app = builder.Build(); app.UseHttpsRedirection(); app.UseInject(string.Empty); app.MapGet("/hello", () => { return "Hello, Furion"; }); app.Run(); ``` -------------------------------- ### Set Default Example Value for API Parameters Source: https://rightpolice.github.io/Furion-Documentation/docs/specification-document Customize the default 'Example Value' for API input parameters by adding XML comments with the tag. This provides more meaningful default data in Swagger UI. ```csharp /// /// 年龄 /// /// 13 [Required, Range(10, 110)] public int Age { get; set; } ``` -------------------------------- ### JSON Schema Configuration Example Source: https://rightpolice.github.io/Furion-Documentation/docs/upgrade Example of a Furion application's JSON configuration file with the $schema property pointing to the Furion JSON Schema for intelligent tips and validation. ```json { "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json", "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information", "Microsoft.EntityFrameworkCore": "Information" } }, "AllowedHosts": "*" } ``` -------------------------------- ### JobDetail Monitor Output Example Source: https://rightpolice.github.io/Furion-Documentation/docs/job This example displays the formatted output for a `JobDetail` object when converted to its monitor string representation. It includes details like job name, type, assembly, and timestamps. ```text info: 2022-12-02 18:04:06.2833095 +08:00 星期五 L MyJob[0] #8 ┏━━━━━━━━━━━ JobDetail ━━━━━━━━━━━ ┣ MyJob ┣ ┣ jobId: job1 ┣ groupName: ┣ jobType: MyJob ┣ assemblyName: ConsoleApp32 ┣ description: ┣ concurrent: True ┣ includeAnnotations: False ┣ properties: {} ┣ updatedTime: 2022-12-02 18:04:06.254 ┗━━━━━━━━━━━ JobDetail ━━━━━━━━━━━ ``` -------------------------------- ### Basic Repository Query Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-hight-query A simple example of querying entities from a repository. This snippet demonstrates a basic filtering operation. ```csharp var posts = repository.Where(u => u.Id > 10).ToList(); ``` -------------------------------- ### Trigger Monitor Output Example Source: https://rightpolice.github.io/Furion-Documentation/docs/job This example shows the formatted output for a trigger object when converted to its monitor string representation. It details trigger type, associated job, schedule parameters, and execution status. ```text info: 2022-12-02 18:04:06.2868205 +08:00 星期五 L MyJob[0] #8 ┏━━━━━━━━━━━ Trigger ━━━━━━━━━━━ ┣ Furion.Schedule.PeriodSecondsTrigger ┣ ┣ triggerId: job1_trigger1 ┣ jobId: job1 ┣ triggerType: Furion.Schedule.PeriodSecondsTrigger ┣ assemblyName: Furion ┣ args: [5] ┣ description: ┣ status: Running ┣ startTime: ┣ endTime: ┣ lastRunTime: 2022-12-02 18:04:06.189 ┣ nextRunTime: 2022-12-02 18:04:11.212 ┣ numberOfRuns: 1 ┣ maxNumberOfRuns: 0 ┣ numberOfErrors: 0 ┣ maxNumberOfErrors: 0 ┣ numRetries: 0 ┣ retryTimeout: 1000 ┣ startNow: True ┣ runOnStart: False ┣ resetOnlyOnce: True ┣ result: ┣ elapsedTime: 100 ┣ updatedTime: 2022-12-02 18:04:06.254 ┗━━━━━━━━━━━ Trigger ━━━━━━━━━━━ ``` -------------------------------- ### Install Spectre.Console.Cli Source: https://rightpolice.github.io/Furion-Documentation/docs/dotnet-tools Install the Spectre.Console.Cli NuGet package to add advanced console UI components to your .NET project. ```bash dotnet add package Spectre.Console.Cli ``` -------------------------------- ### Dynamic SQL Queries with System.Linq.Dynamic.Core Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-hight-query Shows how to use dynamic SQL queries with Furion by installing and utilizing the System.Linq.Dynamic.Core library. Supports string-based WHERE, ORDERBY, and SELECT clauses. ```csharp // 示例一 var query = repository.AsQueryable() .Where("City == @0 and Orders.Count >= @1", "China", 10) .OrderBy("CompanyName") .Select("new(CompanyName as Name, Phone)"); // 示例二 var list = repository.AsQueryable() .Where("Name.Contains(@0)","Furion") .ToList(); // 示例三,支持 ? 语法 var customers = repository.AsQueryable() .Include(c => c.Location) .Where(c => c.Location?.Name == "test") // 注意 Location?.Name .ToList(); ``` -------------------------------- ### Console Logging Output Example Source: https://rightpolice.github.io/Furion-Documentation/docs/logging Demonstrates the default console output format for logs in ASP.NET Core applications. The ConsoleLoggerProvider is registered by default. ```log info: Furion.EventBus.EventBusHostedService[0] EventBus Hosted Service is running. info: Microsoft.Hosting.Lifetime[14] Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: C:\Workplaces\Furion\samples\Furion.Web.Entry\ ``` -------------------------------- ### Bulk Insert and Update with SqlSugar Source: https://rightpolice.github.io/Furion-Documentation/docs/sqlsugar Demonstrates efficient bulk insertion and updating of a million records. Includes examples for updating without a primary key and setting a specific table name or page size. ```csharp //Insert A million only takes a few seconds db.Fastest().BulkCopy(GetList()); //update A million only takes a few seconds db.Fastest().BulkUpdate(GetList());//A million only takes a few seconds完 db.Fastest().BulkUpdate(GetList(),new string[]{"id"},new string[]{"name","time"})//no primary key //if exists update, else insert var x= db.Storageable(data).ToStorage(); x.BulkCopy(); x.BulkUpdate(); //set table name db.Fastest().AS("tableName").BulkCopy(GetList()) //set page db.Fastest().PageSize(300000).BulkCopy(insertObjs); ``` -------------------------------- ### Custom Job Implementation Source: https://rightpolice.github.io/Furion-Documentation/docs/job Example of a custom job class that logs execution context. It requires an ILogger for logging. ```csharp private readonly ILogger _logger; public MyJob(ILogger logger) { _logger = logger; } public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) { _logger.LogInformation($"{context}"); await Task.CompletedTask; } ``` -------------------------------- ### LoggingMonitor Audit Log Output Example Source: https://rightpolice.github.io/Furion-Documentation/docs/audit An example of the detailed audit log output generated by Furion's LoggingMonitor, including request details, authorization information, parameters, and return information. ```text ┏━━━━━━━━━━━ Logging Monitor ━━━━━━━━━━━ ┣ Furion.Application.TestLoggerServices.GetPerson (Furion.Application) ┣ ┣ 控制器名称: TestLoggerServices ┣ 操作名称: GetPerson ┣ 路由信息: [area]: ; [controller]: test-logger; [action]: person ┣ 请求方式: POST ┣ 请求地址: https://localhost:44316/api/test-logger/person/11 ┣ 来源地址: https://localhost:44316/api/index.html ┣ 浏览器标识: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36 Edg/103.0.1264.62 ┣ 客户端 IP 地址: 0.0.0.1 ┣ 服务端 IP 地址: 0.0.0.1 ┣ 服务端运行环境: Development ┣ 执行耗时: 31ms ┣ ━━━━━━━━━━━━━━━ 授权信息 ━━━━━━━━━━━━━━━ ┣ JWT Token: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsIkFjY291bnQiOiJhZG1pbiIsImlhdCI6MTY1ODcxNjc5NywibmJmIjoxNjU4NzE2Nzk3LCJleHAiOjE2NTg3MTc5OTcsImlzcyI6ImRvdG5ldGNoaW5hIiwiYXVkIjoicG93ZXJieSBGdXJpb24ifQ.VYZkwwqCwlUy3aJjuL-og62I0rkxNQ96kSjEm3VgXtg ┣ ┣ UserId (integer): 1 ┣ Account (string): admin ┣ iat (integer): 1658716797 ┣ nbf (integer): 1658716797 ┣ exp (integer): 1658717997 ┣ iss (string): dotnetchina ┣ aud (string): powerby Furion ┣ ━━━━━━━━━━━━━━━ 参数列表 ━━━━━━━━━━━━━━━ ┣ Content-Type: ┣ ┣ id (Int32): 11 ┣ ━━━━━━━━━━━━━━━ 返回信息 ━━━━━━━━━━━━━━━ ┣ 类型: Furion.Application.Persons.PersonDto ┣ 返回值: {"Id":11,"Name":null,"Age":0,"Address":null,"PhoneNumber":null,"QQ":null,"CreatedTime":"0001-01-01T00:00:00+00:00","Childrens":null,"Posts":null} ┗━━━━━━━━━━━ Logging Monitor ━━━━━━━━━━━ ``` -------------------------------- ### Install SignalR TypeScript Client Source: https://rightpolice.github.io/Furion-Documentation/docs/signalr Install the Microsoft SignalR TypeScript client package to enable communication with your SignalR server. This package is essential for invoking server methods like SendMessage. ```bash npm i @microsoft/signalr @types/node ``` -------------------------------- ### Using IDistributedCache Interface Source: https://rightpolice.github.io/Furion-Documentation/docs/cache Demonstrates how to inject and use the `IDistributedCache` interface for getting and setting cached data. Includes setting sliding expiration. ```csharp public class IndexModel : PageModel { private readonly IDistributedCache _cache; public IndexModel(IDistributedCache cache) { _cache = cache; } public string CachedTimeUTC { get; set; } public async Task OnGetAsync() { CachedTimeUTC = "Cached Time Expired"; // Get distributed cache var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC"); if (encodedCachedTimeUTC != null) { CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC); } } public async Task OnPostResetCachedTime() { var currentTimeUTC = DateTime.UtcNow.ToString(); byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC); // Set distributed cache var options = new DistributedCacheEntryOptions() .SetSlidingExpiration(TimeSpan.FromSeconds(20)); await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options); return RedirectToPage(); } } ``` -------------------------------- ### Implement Serial Task Execution Source: https://rightpolice.github.io/Furion-Documentation/docs/process-service Shows how to modify the `BackgroundService` to execute tasks serially, ensuring one task completes before the next one starts, by using a lock mechanism. ```csharp using Furion.TimeCrontab; namespace WorkerService; public class Worker : BackgroundService { private readonly ILogger _logger; private readonly Crontab _crontab; private bool _isLock = false; public Worker(ILogger logger) { _logger = logger; _crontab = Crontab.Parse("* * * * * *", CronStringFormat.WithSeconds); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { if (_isLock) goto next; _isLock = true; var taskFactory = new TaskFactory(System.Threading.Tasks.TaskScheduler.Current); var task = await taskFactory.StartNew(async () => { // 模拟耗时操作 await Task.Delay(2000); _logger.LogInformation("Worker running at: {time}", DateTime.Now); await Task.CompletedTask; }, stoppingToken); // 等待任务完成 await task.ContinueWith(task => _isLock = false); next: await Task.Delay(_crontab.GetSleepTimeSpan(DateTime.Now), stoppingToken); } } } ``` -------------------------------- ### Job Trigger Configuration with Attributes Source: https://rightpolice.github.io/Furion-Documentation/docs/job Example of configuring a job trigger using attributes, specifying interval and description. Ensure the job class implements IJob. ```csharp [PeriodSeconds(5, TriggerId = "trigger1", Description = "这是一段描述")] public class MyJob : IJob { // ... } ``` -------------------------------- ### Getting DbContext using the Db Static Class Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext Illustrates various methods provided by the `Db` static class to obtain DbContext instances, including default, locator-based, and new instances. Remember to use `using` for newly created contexts and pass `serviceProvider` for background threads. ```csharp // 获取默认数据库上下文 var dbContext = Db.GetDbContext(); // 获取定位器数据库上下文 var locatorDbContext = Db.GetDbContext(); var locatorDbContext2 = Db.GetDbContext(typeof(TDbContextLocator)); // 创建新的默认数据库上下文(相当于 new YourDbContext) using var dbContext = Db.GetNewDbContext(); // 别忘记 using,Furion 4.8.8.55+ 版本有效 // 创建新的定位器数据库上下文(相当于 new YourDbContext) using var locatorDbContext = Db.GetNewDbContext(); // 别忘记 using,Furion 4.8.8.55+ 版本有效 using var locatorDbContext2 = Db.GetNewDbContext(typeof(TDbContextLocator)); // 别忘记 using,Furion 4.8.8.55+ 版本有效 ``` -------------------------------- ### Mixed Order Query Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-hight-query Demonstrates how to apply a mix of ascending and descending order clauses in a single query. This example sorts by ID ascending, then by Name descending, and finally by Age ascending. ```csharp // 示例一 var query = repository.AsQueryable() .OrderBy(u => u.Id) .OrderByDescending(u => u.Name) .ThenBy(u => u.Age); ``` -------------------------------- ### Stored Procedure Definition with Input, Output, and Return Parameters Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-proc Example SQL script defining a stored procedure that accepts an input parameter, provides output parameters, returns a value, and outputs result sets. ```sql CREATE PROC PROC_Output @Id INT, // 输入参数 @Name NVARCHAR(32) OUTPUT, // 输出参数,还带长度 @Age INT OUTPUT // 输出参数 AS BEGIN SET @Name = 'Furion Output'; // 输出结果集 SELECT * FROM dbo.Test WHERE Id > @Id; // 输出结果集 SELECT TOP 10 * FROM dbo.Test; SET @Age = 27; // 带 RETURN 返回 RETURN 10; END; ``` -------------------------------- ### Job Execution Log Output Source: https://rightpolice.github.io/Furion-Documentation/docs/job Example log output demonstrating the execution of a job and the custom job monitor's logging for pre-execution, post-execution, and exception handling. ```log info: 2022-12-05 14:09:47.2337395 +08:00 星期一 L System.Logging.ScheduleService[0] #1 Schedule hosted service is running. info: 2022-12-05 14:09:47.2401561 +08:00 星期一 L System.Logging.ScheduleService[0] #1 Schedule hosted service is preloading... info: 2022-12-05 14:09:47.2780446 +08:00 星期一 L System.Logging.ScheduleService[0] #1 The trigger for scheduler of successfully appended to the schedule. info: 2022-12-05 14:09:47.2810119 +08:00 星期一 L System.Logging.ScheduleService[0] #1 The scheduler of successfully appended to the schedule. warn: 2022-12-05 14:09:47.2941716 +08:00 星期一 L System.Logging.ScheduleService[0] #1 Schedule hosted service preload completed, and a total of <1> schedulers are appended. info: 2022-12-05 14:09:52.3190129 +08:00 星期一 L ConsoleApp32.YourJobMonitor[0] #4 执行之前: [C] 5s 1ts 2022-12-05 14:09:52.241 -> 2022-12-05 14:09:57.260 info: 2022-12-05 14:09:52.3240208 +08:00 星期一 L MyJob[0] #4 [C] 5s 1ts 2022-12-05 14:09:52.241 -> 2022-12-05 14:09:57.260 fail: 2022-12-05 14:09:52.5253398 +08:00 星期一 L System.Logging.ScheduleService[0] #4 Error occurred executing [C] 5s 1ts 2022-12-05 14:09:52.241 -> 2022-12-05 14:09:57.260. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ System.Exception: 模拟出错 at MyJob.ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) in D:\Workplaces\Study\CSharp\ConsoleApp32\ConsoleApp32\Program.cs:line 28 at Furion.Schedule.ScheduleHostedService.<>c__DisplayClass23_3.<b__3>d.MoveNext() in D:\Workplaces\OpenSources\Furion\framework\Furion\Schedule\HostedServices\ScheduleHostedService.cs:line 220 --- End of stack trace from previous location --- at Furion.FriendlyException.Retry.InvokeAsync(Func`1 action, Int32 numRetries, Int32 retryTimeout, Boolean finalThrow, Type[] exceptionTypes, Func`2 fallbackPolicy, Action`2 retryAction) in D:\Workplaces\OpenSources\Furion\framework\Furion\FriendlyException\Retry.cs:line 87 at Furion.Schedule.ScheduleHostedService.<>c__DisplayClass23_2.<b__2>d.MoveNext() in D:\Workplaces\OpenSources\Furion\framework\Furion\Schedule\HostedServices\ScheduleHostedService.cs:line 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ info: 2022-12-05 14:09:52.5288429 +08:00 星期一 L ConsoleApp32.YourJobMonitor[0] #4 执行之后: [C] 5s 1ts 2022-12-05 14:09:52.241 -> 2022-12-05 14:09:57.260 fail: 2022-12-05 14:09:52.5318526 +08:00 星期一 L ConsoleApp32.YourJobMonitor[0] #4 执行出错啦: [C] 5s 1ts 2022-12-05 14:09:52.241 -> 2022-12-05 14:09:57.260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ System.InvalidOperationException: Error occurred executing [C] 5s 1ts 2022-12-05 14:09:52.241 -> 2022-12-05 14:09:57.260. ---> System.Exception: 模拟出错 at MyJob.ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) in D:\Workplaces\Study\CSharp\ConsoleApp32\ConsoleApp32\Program.cs:line 28 at Furion.Schedule.ScheduleHostedService.<>c__DisplayClass23_3.<b__3>d.MoveNext() in D:\Workplaces\OpenSources\Furion\framework\Furion\Schedule\HostedServices\ScheduleHostedService.cs:line 220 --- End of stack trace from previous location --- at Furion.FriendlyException.Retry.InvokeAsync(Func`1 action, Int32 numRetries, Int32 retryTimeout, Boolean finalThrow, Type[] exceptionTypes, Func`2 fallbackPolicy, Action`2 retryAction) in D:\Workplaces\OpenSources\Furion\framework\Furion\FriendlyException\Retry.cs:line 87 ``` -------------------------------- ### Ascending Order Query Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-hight-query Shows how to sort query results in ascending order. The first example sorts by a single column, and the second demonstrates secondary sorting using ThenBy. ```csharp // 示例一 var query = repository.AsQueryable() .OrderBy(u => u.Id); ``` ```csharp // 示例二 var query =repository.AsQueryable() .OrderBy(u => u.Id) .ThenBy(u => u.Name); ``` -------------------------------- ### SQL Proxy: Fetch Tuple with Person and List of Persons Source: https://rightpolice.github.io/Furion-Documentation/docs/upgrade Example showing the SQL proxy's ability to return a ValueTuple containing a single 'Person' object and a list of 'Person' objects from multiple SQL statements. ```csharp public interface ISql : ISqlDispatchProxy { [SqlExecute(@" select * from person where id =@id; select * from person")] (Person, List) GetData(int id); // Return value is a combination of (Person, List) } ``` -------------------------------- ### Configuring Lazy Loading for DbContext Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext Shows how to configure lazy loading for entities by installing the EFCore Proxies package, registering the DbContext with `AddDb`, and overriding the `OnConfiguring` method to use `UseLazyLoadingProxies()`. ```csharp using Furion.DatabaseAccessor; using Microsoft.EntityFrameworkCore; namespace Furion.EntityFramework.Core { [AppDbContext("Sqlite3ConnectionString", DbProvider.Sqlite)] public class DefaultDbContext : AppDbContext { public DefaultDbContext(DbContextOptions options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseLazyLoadingProxies() .UseSqlite(DbProvider.GetConnectionString()); base.OnConfiguring(optionsBuilder); } } } ``` -------------------------------- ### Global Log Filtering in .NET 6+ Source: https://rightpolice.github.io/Furion-Documentation/docs/logging Provides examples of implementing global log filtering in .NET 6 and later versions using WebApplicationBuilder. This method allows for centralized control over log output. ```csharp var builder = WebApplication.CreateBuilder(args); builder.Logging.AddFilter((provider, category, logLevel) => { return !new[] { "Microsoft.Hosting", "Microsoft.AspNetCore" }.Any(u => category.StartsWith(u)) && logLevel >= LogLevel.Information; }); ``` ```csharp Serve.Run(RunOptions.Default.AddWebComponent()); public class WebComponent : IWebComponent { public void Load(WebApplicationBuilder builder, ComponentContext componentContext) { builder.Logging.AddFilter((provider, category, logLevel) => { return !new[] { "Microsoft.Hosting", "Microsoft.AspNetCore" }.Any(u => category.StartsWith(u)) && logLevel >= LogLevel.Information; }); } } ``` -------------------------------- ### SignalR Hub Configuration in Startup.cs Source: https://rightpolice.github.io/Furion-Documentation/docs/signalr Equivalent configuration for SignalR Hubs in the Startup.cs file using app.UseEndpoints. ```csharp app.UseEndpoints(endpoints => { var builder = endpoints.MapHub("/hubs/chathub", options => { // Configuration }); }); ``` -------------------------------- ### Configure Database Logging with Default Settings Source: https://rightpolice.github.io/Furion-Documentation/docs/logging Basic configuration for adding database logging using a custom writer with default settings. ```csharp // Example 1, default configuration services.AddDatabaseLogging(options => {}); ``` -------------------------------- ### Configure Hub Registration Options Source: https://rightpolice.github.io/Furion-Documentation/docs/signalr Configure additional parameters like permissions and cross-origin settings when registering a Hub by implementing static methods within the Hub class. ```csharp using Furion.InstantMessaging; using Microsoft.AspNetCore.SignalR; using System; using System.Threading.Tasks; namespace Furion.Core { [MapHub("/hubs/chathub")] public class ChatHub : Hub { // Other code public static void HttpConnectionDispatcherOptionsSettings(HttpConnectionDispatcherOptions options) { // Configuration } public static void HubEndpointConventionBuilderSettings(HubEndpointConventionBuilder Builder) { // Configuration } } } ``` -------------------------------- ### Get Hub Instance via IHubContext Injection Source: https://rightpolice.github.io/Furion-Documentation/docs/signalr Obtain an instance of IHubContext by injecting it into a controller or service. This is the default singleton registration. ```csharp public class HomeController : Controller { private readonly IHubContext _hubContext; public HomeController(IHubContext hubContext) { _hubContext = hubContext; } public async Task Index() { await _hubContext.Clients.All.SendAsync("Notify", $"Home page loaded at: {DateTime.Now}"); return View(); } } ``` -------------------------------- ### Repository CRUD and Query Operations Source: https://rightpolice.github.io/Furion-Documentation/docs/sqlsugar Demonstrates various repository methods for querying (GetById, GetSingle, GetFirst, GetList, GetPageList), inserting (Insert, InsertRange, InsertReturnIdentity), deleting (Delete, DeleteById, DeleteByIds), and updating (Update, UpdateRange). ```csharp //查询 var data1 = base.GetById(1);//根据id查询 var data4 = base.GetSingle(it => it.Id == 1);//查询单条记录,结果集不能超过1,不然会提示错误 var data = base.GetFirst(it => it.Id == 1);//查询第一条记录 var data2 = base.GetList();//查询所有 var data3 = base.GetList(it => it.Id == 1); //根据条件查询 var p = new PageModel() { PageIndex = 1, PageSize = 2 }; var data5 = base.GetPageList(it => it.Name == "xx", p); Console.Write(p.PageCount); var data6 = base.GetPageList(it => it.Name == "xx", p, it => it.Name, OrderByType.Asc); Console.Write(p.PageCount); List conModels = new List(); conModels.Add(new ConditionalModel(){FieldName="id",ConditionalType=ConditionalType.Equal,FieldValue="1"});//id=1 var data7 = base.GetPageList(conModels, p, it => it.Name, OrderByType.Asc); base.AsQueryable().Where(x => x.Id == 1).ToList(); //插入 base.Insert(insertObj); base.InsertRange(InsertObjs); var id = base.InsertReturnIdentity(insertObj); base.AsInsertable(insertObj).ExecuteCommand(); //删除 base.Delete(insertObj); base.DeleteById(1); base.DeleteByIds(new object [] { 1, 2 }); //数组带是 ids方法 ,封装传 object [] 类型 base.Delete(it => it.Id == 1); base.AsDeleteable().Where(it => it.Id == 1).ExecuteCommand(); //更新 base.Update(insertObj); base.UpdateRange(InsertObjs); base.Update(it => new Order() { Name = "a", }, it => it.Id == 1); base.AsUpdateable(insertObj).UpdateColumns(it=>new { it.Name }).ExecuteCommand(); //高级操作 base.AsSugarClient // 获取完整的db对象 base.AsTenant // 获取多库相关操作 //切换仓储 base.ChangeRepository>() //支持多租户和扩展方法,使用SqlSugarScope单例(或者SqlSugarClient Scope注入) base.Change()//只支持自带方法和单库 ``` -------------------------------- ### Add WebView2 Package Source: https://rightpolice.github.io/Furion-Documentation/docs/bs-to-cs Command to add the Microsoft.Web.WebView2 package to your project. Avoid version 1.0.1722.32 due to known issues. ```bash dotnet add package Microsoft.Web.WebView2 ``` -------------------------------- ### SQL Proxy: Fetch Single Person by ID Source: https://rightpolice.github.io/Furion-Documentation/docs/upgrade Demonstrates how the SQL proxy can be used to fetch a single 'Person' object by ID using a parameterized query. ```csharp public interface ISql : ISqlDispatchProxy { // Collection types [SqlExecute("select * from person")] List GetPersons(); // Since v3.7.3+ supports returning single class type parameters [SqlExecute("select * from person where id=@id")] Person GetPerson(int id); } ``` -------------------------------- ### Configure SwaggerGen in Services Source: https://rightpolice.github.io/Furion-Documentation/docs/specification-document Customize Swagger generation options by configuring SwaggerGen within the AddInject method in ConfigureServices. This allows for advanced Swagger setup. ```csharp public void ConfigureServices(IServiceCollection services) { services.AddInject(options => { options.ConfigureSwaggerGen(gen => { // .... }); }); } ``` -------------------------------- ### Switching Databases with Sql Proxy Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-sql-proxy Explains the three methods for switching the database context when using the Sql proxy: single method attribute, interface attribute, and runtime `.Change` method. ```APIDOC ## Switching Databases with Sql Proxy ### Description Provides three ways to specify which database context the Sql proxy should use for execution. ### 1. Single Method Attribute (`[SqlDbContextLocator]`) Apply the `[SqlDbContextLocator]` attribute directly to a method to specify its database context. #### Example ```csharp [SqlExecute("select * from person"), SqlDbContextLocator(typeof(MySqlDbContextLocator))] List GetPerson(); ``` ### 2. Interface Attribute (`[SqlDbContextLocator]`) Apply the `[SqlDbContextLocator]` attribute to an interface. All methods within that interface will then use the specified database context. #### Example ```csharp [SqlDbContextLocator(typeof(MySqlDbContextLocator))] public interface ISql : ISqlDispatchProxy { [SqlFunction("FN_Name")] // Scalar function string GetValue(MyParam dto); [SqlProcedure("FN_Name")] // Table-valued function List GetPersons(int id); } ``` ### 3. Runtime `.Change` Method Dynamically switch the database context at runtime using the `.Change()` method on the Sql proxy instance. #### Example ```csharp // Switch to a specific database _sql.Change(); _sql.GetPerson(); // Switch multiple times _sql.Change(); _sql.GetPerson(); // Reset to the initial database context _sql.ResetIt(); _sql.GetPerson(); ``` ### Priority The priority for database context selection is: `.Change<>` > Method `[SqlDbContextLocator]` > Interface `[SqlDbContextLocator]`. ### Default If no `DbContextLocator` is specified, `MasterDbContextLocator` is used by default. ``` -------------------------------- ### Descending Order Query Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-hight-query Illustrates sorting query results in descending order. The first example sorts by a single column, and the second shows secondary sorting with ThenByDescending. ```csharp // 示例一 var query = repository.AsQueryable() .OrderByDescending(u => u.Id); ``` ```csharp // 示例二 var query =repository.AsQueryable() .OrderByDescending(u => u.Id) .ThenByDescending(u => u.Name); ``` -------------------------------- ### Execute Git Commit Command with CliWrap Source: https://rightpolice.github.io/Furion-Documentation/docs/dotnet-tools Demonstrates executing a 'git commit' command using CliWrap, showing both string and array argument formats. ```csharp // 字符串参数方式 var cmd = Cli.Wrap("git") .WithArguments("commit -m \"my commit\""); // 数组参数方式 var cmd = Cli.Wrap("git") .WithArguments(new[] {"commit", "-m", "my commit"}); // 执行命令 var result = cmd.ExecuteAsync(); ``` -------------------------------- ### Dynamic Database Switching with .Change() Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-sql-proxy Dynamically switch the database context at runtime using the `.Change()` method on the SQL proxy. This allows for flexible database routing based on application logic. Use `.ResetIt()` to revert to the initial state. ```csharp // Switch sql proxy database to a specific database _sql.Change(); _sql.GetPerson(); // Multiple switches _sql.Change(); _sql.GetPerson(); // Also supports resetting the database context locator to the initial state _sql.ResetIt(); _sql.GetPerson(); ``` -------------------------------- ### Configure Database Logging with Custom Settings Source: https://rightpolice.github.io/Furion-Documentation/docs/logging Configure database logging with custom settings, such as specifying the minimum log level. ```csharp // Example 2: Custom configuration services.AddDatabaseLogging(options => { options.MinimumLevel = LogLevel.Warning; // Other configurations... }); ``` -------------------------------- ### Configure NCache Distributed Cache Source: https://rightpolice.github.io/Furion-Documentation/docs/cache Register the NCache distributed cache service after installing the SDK and configuring the cache cluster. Specify the cache name and enable logging/exceptions if needed. ```csharp services.AddNCacheDistributedCache(configuration => { configuration.CacheName = "demoClusteredCache"; configuration.EnableLogs = true; configuration.ExceptionsEnabled = true; }); ``` -------------------------------- ### Define a Generic Repository Class Source: https://rightpolice.github.io/Furion-Documentation/docs/sqlsugar Create a generic repository class that extends SimpleClient to leverage repository APIs. It supports dependency injection and manual context retrieval for repository switching. ```csharp public class Repository : SimpleClient where T : class, new() { public Repository(ISqlSugarClient context = null) : base(context)//默认值等于null不能少 { base.Context = App.GetService();//用手动获取方式支持切换仓储 } } ``` -------------------------------- ### Compile C# Class Code to Assembly Source: https://rightpolice.github.io/Furion-Documentation/docs/global/app Compiles a C# class definition string into an assembly. This allows you to get the runtime type of the compiled class. Requires Furion 4.8.8.7+. ```csharp var jobAssembly = App.CompileCSharpClassCode(@" using Furion.Schedule; using Microsoft.Extensions.Logging; using System; using System.Threading; using System.Threading.Tasks; namespace YourProject; public class MyJob : IJob { private readonly ILogger _logger; public MyJob(ILogger logger) { _logger = logger; } public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken) { _logger.LogInformation($"我是 Roslyn 方式创建的:{context}"); await Task.CompletedTask; } } "); // 生成运行时 MyJob 类型 var jobType = jobAssembly.GetType("YourProject.MyJob"); ``` -------------------------------- ### Customize Swagger Schema IDs Source: https://rightpolice.github.io/Furion-Documentation/docs/specification-document Customize how schema IDs are generated in Swagger by using the CustomSchemaIds method within ConfigureSwaggerGen. This example sets the schema ID to the full type name. ```csharp services.AddControllersWithViews() .AddInject(options => { options.ConfigureSwaggerGen(gen => { gen.CustomSchemaIds(x => x.FullName); }); }); ``` -------------------------------- ### Define Sharded Table Query Source: https://rightpolice.github.io/Furion-Documentation/docs/dbcontext-hight-query Configure a Person entity to query data from multiple sharded tables using ToSqlQuery. This example demonstrates querying unioned tables for specific dates. ```csharp using Furion.DatabaseAccessor; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using System; using System.Collections.Generic; namespace Furion.Core { public class Person : Entity, IEntityTypeBuilder { public string Name { get; set; } /// /// 配置实体关系 /// /// /// /// public void Configure(EntityTypeBuilder entityBuilder, DbContext dbContext, Type dbContextLocator) { entityBuilder.ToSqlQuery( @"select * from dbo.person.2020-09-19 union all select * from dbo.person.2020-09-20"); } } } ``` -------------------------------- ### Dependency Injection in Worker Service Source: https://rightpolice.github.io/Furion-Documentation/docs/process-service Illustrates how to manually create a scope to inject transient or scoped services within a `BackgroundService`, as only singleton scope is provided by default. ```csharp public class Worker : BackgroundService { // 日志对象 private readonly ILogger _logger; // 服务工厂 private readonly IServiceScopeFactory _scopeFactory; public Worker(ILogger logger , IServiceScopeFactory scopeFactory) { _logger = logger; _scopeFactory = scopeFactory; } protected override Task ExecuteAsync(CancellationToken stoppingToken) { // 放在循环外可以避免高频下频繁创建作用域和解析服务 using var scope = _scopeFactory.CreateScope(); var services = scope.ServiceProvider; while (!stoppingToken.IsCancellationRequested) { // 放在循环内针对频率不是很高的操作 // using var scope = _scopeFactory.CreateScope(); // var services = scope.ServiceProvider; // 获取数据库上下文 var dbContext = Db.GetDbContext(services); // 获取仓储 var respository = Db.GetRepository(services); // 解析其他服务 var otherService = services.GetService(); } return Task.CompletedTask; } } ``` -------------------------------- ### Configure Custom Resource File Prefix Source: https://rightpolice.github.io/Furion-Documentation/docs/local-language Customize the prefix for resource files and optionally specify the assembly name in the configuration. ```json { "LocalizationSettings": { "LanguageFilePrefix": "MyLang" // "AssemblyName": "你的其他层程序集名称" } } ``` -------------------------------- ### Get Recent Job Run Timelines Source: https://rightpolice.github.io/Furion-Documentation/docs/job Retrieve the last 5 job trigger run records from memory using the GetTimelines() method. This feature is available from Furion version 4.8.4.3+. ```csharp var timelines = trigger.GetTimelines(); // => [{numberOfRuns: 2, lastRunTime: "2023-01-03 14:00:08"}, {numberOfRuns: 1, lastRunTime: "2023-01-03 14:00:03"}, ...] ``` -------------------------------- ### Registering Schedule Services Source: https://rightpolice.github.io/Furion-Documentation/docs/job Dynamically add jobs by registering the services. You can either fully dynamically register or partially static and partially dynamic. ```csharp services.AddSchedule(); services.AddSchedule(options => { options.AddJob(concurrent: false, Triggers.PeriodSeconds(5)); }); ```