解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
10.23 KiB
X
# ÔËÐÐʱÐÅÏ¢ Runtime ## ¸ÅÊö `Runtime` ÊÇ NewLife.Core ÖеÄÔËÐÐʱÐÅÏ¢¹¤¾ßÀ࣬Ìṩµ±Ç°ÔËÐл·¾³µÄ¸÷ÖÖ¼ì²âºÍ²Ù×÷¹¦ÄÜ¡£°üÀ¨²Ù×÷ϵͳÅжϡ¢»·¾³±äÁ¿¶ÁÈ¡¡¢ÄÚ´æ¹ÜÀí¡¢½ø³ÌÐÅÏ¢µÈ¹¦ÄÜ£¬ÊÇ¿çÆ½Ì¨¿ª·¢µÄÖØÒª»ù´¡×é¼þ¡£ **ÃüÃû¿Õ¼ä**£º`NewLife` **ÎĵµµØÖ·**£ºhttps://newlifex.com/core/runtime ## ºËÐÄÌØÐÔ - **ƽ̨¼ì²â**£ºWindows¡¢Linux¡¢OSX¡¢Mono¡¢Unity µÈÔËÐл·¾³Ê¶±ð - **»·¾³ÅжÏ**£º¿ØÖÆÌ¨¡¢Web¡¢ÈÝÆ÷µÈÓ¦ÓÃÀàÐͼì²â - **¸ß¾«¶È¼ÆÊ±**£º¿çƽ̨µÄ `TickCount64` ʵÏÖ£¬±ÜÃâ 32 λÒç³ö - **ÄÚ´æ¹ÜÀí**£ºGC »ØÊպ͹¤×÷¼¯ÊÍ·Å - **»·¾³±äÁ¿**£º²»Çø·Ö´óСдµÄ»·¾³±äÁ¿¶ÁÈ¡ ## ¿ìËÙ¿ªÊ¼ ```csharp using NewLife; // ÅжϲÙ×÷ϵͳ if (Runtime.Windows) Console.WriteLine("ÔËÐÐÔÚ Windows ϵͳÉÏ"); else if (Runtime.Linux) Console.WriteLine("ÔËÐÐÔÚ Linux ϵͳÉÏ"); // ÅжÏÔËÐл·¾³ if (Runtime.IsConsole) Console.WriteLine("¿ØÖÆÌ¨Ó¦ÓÃ"); if (Runtime.Container) Console.WriteLine("ÔËÐÐÔÚÈÝÆ÷ÖÐ"); // »ñȡϵͳÔËÐÐʱ¼ä£¨ºÁÃ룩 var uptime = Runtime.TickCount64; Console.WriteLine($"ϵͳÒÑÔËÐÐ {uptime / 1000 / 60} ·ÖÖÓ"); // »ñÈ¡µ±Ç°½ø³ÌID var pid = Runtime.ProcessId; Console.WriteLine($"µ±Ç°½ø³ÌID: {pid}"); // ÊÍ·ÅÄÚ´æ Runtime.FreeMemory(); ``` ## API ²Î¿¼ ### ƽ̨¼ì²â #### Windows ```csharp public static Boolean Windows { get; } ``` ÊÇ·ñ Windows ²Ù×÷ϵͳ¡£ **ʵÏÖ·½Ê½**£º - .NET Core/.NET 5+£ºÊ¹Óà `RuntimeInformation.IsOSPlatform(OSPlatform.Windows)` - .NET Framework£º¼ì²é `Environment.OSVersion.Platform` **ʾÀý**£º ```csharp if (Runtime.Windows) { // Windows ÌØÓеIJÙ×÷£¬Èçµ÷Óà Win32 API Console.WriteLine("Windows °æ±¾: " + Environment.OSVersion.VersionString); } ``` #### Linux ```csharp public static Boolean Linux { get; } ``` ÊÇ·ñ Linux ²Ù×÷ϵͳ¡£ **ʾÀý**£º ```csharp if (Runtime.Linux) { // Linux ÌØÓеIJÙ×÷£¬Èç¶ÁÈ¡ /proc Îļþϵͳ var cpuInfo = File.ReadAllText("/proc/cpuinfo"); } ``` #### OSX ```csharp public static Boolean OSX { get; } ``` ÊÇ·ñ macOS ²Ù×÷ϵͳ¡£ #### Mono ```csharp public static Boolean Mono { get; } ``` ÊÇ·ñÔÚ Mono ÔËÐÐʱ»·¾³ÖÐÔËÐС£Í¨¹ý¼ì²â `Mono.Runtime` ÀàÐÍÊÇ·ñ´æÔÚÀ´Åжϡ£ **Ó¦Óó¡¾°**£º - ijЩ API ÔÚ Mono ÏÂÐÐΪ²»Í¬ - Õë¶Ô Mono ½øÐÐÌØÊâÓÅ»¯»ò¼æÈÝ´¦Àí #### Unity ```csharp public static Boolean Unity { get; } ``` ÊÇ·ñÔÚ Unity ÒýÇæ»·¾³ÖÐÔËÐС£Í¨¹ý¼ì²â `UnityEngine.Application` ÀàÐÍÊÇ·ñ´æÔÚÀ´Åжϡ£ ### »·¾³ÅÐ¶Ï #### IsConsole ```csharp public static Boolean IsConsole { get; set; } ``` ÊÇ·ñ¿ØÖÆÌ¨Ó¦ÓóÌÐò¡£ **ÅжÏÂß¼­**£º 1. ³¢ÊÔ·ÃÎÊ `Console.ForegroundColor` ´¥·¢¿ØÖÆÌ¨¿ÉÓÃÐÔ¼ì²é 2. ¼ì²éµ±Ç°½ø³ÌÊÇ·ñÓÐÖ÷´°¿Ú¾ä±ú 3. ÈκÎÒì³£¶¼ÊÓΪ·Ç¿ØÖÆÌ¨»·¾³ **ʾÀý**£º ```csharp if (Runtime.IsConsole) { Console.WriteLine("ÕâÊÇ¿ØÖÆÌ¨Ó¦Ó㬿ÉÒÔʹÓòÊÉ«Êä³ö"); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("ÂÌÉ«Îı¾"); Console.ResetColor(); } else { // GUI Ó¦Óûò·þÎñ Debug.WriteLine("·Ç¿ØÖÆÌ¨»·¾³"); } ``` > **×¢Òâ**£º¿ÉÒÔͨ¹ýÉèÖà `Runtime.IsConsole = false` Ç¿ÖÆ½ûÓÿØÖÆÌ¨Åжϡ£ #### Container ```csharp public static Boolean Container { get; } ``` ÊÇ·ñÔÚ Docker/Kubernetes ÈÝÆ÷ÖÐÔËÐС£Í¨¹ý¼ì²é»·¾³±äÁ¿ `DOTNET_RUNNING_IN_CONTAINER` À´Åжϡ£ **ʾÀý**£º ```csharp if (Runtime.Container) { // ÈÝÆ÷»·¾³ÏµÄÌØÊâ´¦Àí // ÀýÈ磺ʹÓÃÈÝÆ÷ÄÚµÄÅäÖ÷¾¶ var configPath = "/app/config"; } ``` #### IsWeb ```csharp public static Boolean IsWeb { get; } ``` ÊÇ·ñ Web Ó¦ÓóÌÐò¡£ **ÅжÏÂß¼­**£º - .NET Core/.NET 5+£º¼ì²éÊÇ·ñ¼ÓÔØÁË `Microsoft.AspNetCore` ³ÌÐò¼¯ - .NET Framework£º¼ì²é `System.Web.HttpRuntime.AppDomainAppId` ÊÇ·ñÓÐÖµ **ʾÀý**£º ```csharp if (Runtime.IsWeb) { // Web Ó¦ÓÃÌØÓеĴ¦Àí // ÀýÈ磺ʹÓà HTTP ÉÏÏÂÎÄÏà¹Ø¹¦ÄÜ } ``` ### ʱ¼äÓë¼ÆÊý #### TickCount64 ```csharp public static Int64 TickCount64 { get; } ``` ϵͳÆô¶¯ÒÔÀ´µÄºÁÃëÊý£¨64룩£¬²»»á·¢Éú 32 λÒç³öÎÊÌâ¡£ **ʵÏÖ·½Ê½**£º - .NET Core 3.1+£ºÖ±½ÓʹÓà `Environment.TickCount64` - Windows ¾É¿ò¼Ü£ºµ÷Óà `GetTickCount64` Win32 API - ÆäËûƽ̨£ºÊ¹Óà `Stopwatch.GetTimestamp()` ¼ÆË㣬»ò»ØÍ˵½ `Environment.TickCount` **Ó¦Óó¡¾°**£º - ¸ß¾«¶È¼ÆÊ± - ¼ÆËãʱ¼ä¼ä¸ô - ±ÜÃâ `Environment.TickCount` Ô¼ 49.7 ÌìÒç³öµÄÎÊÌâ **ʾÀý**£º ```csharp // ²âÁ¿²Ù×÷ºÄʱ var start = Runtime.TickCount64; DoSomeWork(); var elapsed = Runtime.TickCount64 - start; Console.WriteLine($"ºÄʱ: {elapsed} ms"); // ÉèÖó¬Ê± var timeout = Runtime.TickCount64 + 5000; // 5Ãëºó³¬Ê± while (Runtime.TickCount64 < timeout) { if (CheckCondition()) break; Thread.Sleep(100); } ``` #### UtcNow ```csharp public static DateTimeOffset UtcNow { get; } ``` »ñÈ¡µ±Ç° UTC ʱ¼ä¡£»ùÓÚÈ«¾Öʱ¼äÌṩÕߣ¨`TimerScheduler.GlobalTimeProvider`£©£¬ÔÚÐdz¾Ó¦ÓÃÖлáÆÁ±Î·þÎñÆ÷ʱ¼ä²î¡£ **ʾÀý**£º ```csharp var utcNow = Runtime.UtcNow; Console.WriteLine($"UTCʱ¼ä: {utcNow}"); Console.WriteLine($"±¾µØÊ±¼ä: {utcNow.LocalDateTime}"); ``` ### ½ø³ÌÐÅÏ¢ #### ProcessId ```csharp public static Int32 ProcessId { get; } ``` µ±Ç°½ø³Ì ID¡£Ê¹Óûº´æ±ÜÃâÖØ¸´»ñÈ¡¡£ **ʵÏÖ·½Ê½**£º - .NET 5+£ºÊ¹Óà `Environment.ProcessId` - ¾É¿ò¼Ü£ºÊ¹Óà `Process.GetCurrentProcess().Id` **ʾÀý**£º ```csharp Console.WriteLine($"µ±Ç°½ø³ÌID: {Runtime.ProcessId}"); // ÓÃÓÚÈÕÖ¾¼Ç¼ var logPrefix = $"[PID:{Runtime.ProcessId}]"; ``` #### ClientId ```csharp public static String ClientId { get; } ``` ¿Í»§¶Ë±êʶ£¬¸ñʽΪ `ip@pid`¡£ÓÃÓÚ·Ö²¼Ê½ÏµÍ³Öбêʶ¿Í»§¶ËʵÀý¡£ **ʾÀý**£º ```csharp Console.WriteLine($"¿Í»§¶Ë±êʶ: {Runtime.ClientId}"); // Êä³öÀàËÆ: 192.168.1.100@12345 // ÓÃÓÚ·Ö²¼Ê½Ëø¡¢ÏûÏ¢¶ÓÁÐÏû·ÑÕß±êʶµÈ var consumerId = Runtime.ClientId; ``` ### »·¾³±äÁ¿ #### GetEnvironmentVariable ```csharp public static String? GetEnvironmentVariable(String variable) ``` »ñÈ¡»·¾³±äÁ¿£¬**²»Çø·Ö´óСд**¡£ **ÌØµã**£º - Ïȳ¢ÊÔ¾«È·Æ¥Åä - ÈôδÕÒµ½£¬±éÀúËùÓл·¾³±äÁ¿½øÐв»Çø·Ö´óСдµÄ±È½Ï **ʾÀý**£º ```csharp // ²»Çø·Ö´óСд»ñÈ¡»·¾³±äÁ¿ var path = Runtime.GetEnvironmentVariable("PATH"); var home = Runtime.GetEnvironmentVariable("HOME"); var customVar = Runtime.GetEnvironmentVariable("MY_APP_CONFIG"); ``` #### GetEnvironmentVariables ```csharp public static IDictionary<String, String?> GetEnvironmentVariables() ``` »ñÈ¡ËùÓл·¾³±äÁ¿£¬·µ»Ø²»Çø·Ö´óСдµÄ×ֵ䡣 **ʾÀý**£º ```csharp var envVars = Runtime.GetEnvironmentVariables(); foreach (var kv in envVars.Where(e => e.Key.StartsWith("DOTNET"))) { Console.WriteLine($"{kv.Key} = {kv.Value}"); } ``` ### ÅäÖà #### CreateConfigOnMissing ```csharp public static Boolean CreateConfigOnMissing { get; set; } ``` ÅäÖÃÎļþ²»´æÔÚʱ£¬ÊÇ·ñÉú³ÉĬÈÏÅäÖÃÎļþ¡£Ä¬ÈÏΪ `true`¡£ **ÅäÖ÷½Ê½**£º - »·¾³±äÁ¿£º`CreateConfigOnMissing=false` - ´úÂëÉèÖãº`Runtime.CreateConfigOnMissing = false` **ʾÀý**£º ```csharp // Éú²ú»·¾³½ûÖ¹×Ô¶¯´´½¨ÅäÖÃÎļþ Runtime.CreateConfigOnMissing = false; ``` ### ÄÚ´æ¹ÜÀí #### FreeMemory ```csharp public static Boolean FreeMemory(Int32 processId = 0, Boolean gc = true, Boolean workingSet = true) ``` ÊÍ·ÅÄÚ´æ¡£Ö´ÐÐ GC »ØÊÕ²¢Êͷʤ×÷¼¯£¨Windows£©¡£ **²ÎÊý˵Ã÷**£º - `processId`£ºÄ¿±ê½ø³ÌID£¬0 ±íʾµ±Ç°½ø³Ì - `gc`£ºÊÇ·ñÖ´ÐÐ GC »ØÊÕ£¨½öµ±Ç°½ø³ÌÓÐЧ£© - `workingSet`£ºÊÇ·ñÊͷʤ×÷¼¯£¨½ö Windows ÓÐЧ£© **Ö´Ðв½Öè**£º 1. Ö´ÐÐ `GC.Collect` ½øÐÐÀ¬»ø»ØÊÕ 2. µ÷Óà `GC.WaitForPendingFinalizers` µÈ´ýÖÕ½áÆ÷ 3. ÔÙ´ÎÖ´ÐÐ `GC.Collect` 4. µ÷Óà `EmptyWorkingSet` Êͷʤ×÷¼¯£¨Windows£© **ʾÀý**£º ```csharp // ¶¨ÆÚÊÍ·ÅÄÚ´æ var timer = new TimerX(state => { Runtime.FreeMemory(); }, null, 60_000, 60_000); // ÿ·ÖÖÓÖ´ÐÐÒ»´Î // ½öÊͷʤ×÷¼¯£¬²»´¥·¢GC Runtime.FreeMemory(gc: false); // ÊÍ·ÅÖ¸¶¨½ø³ÌµÄÄÚ´æ Runtime.FreeMemory(processId: 1234, gc: false); ``` > **×¢Òâ**£ºÆµ·±µ÷Óà `FreeMemory` ¿ÉÄÜÓ°ÏìÐÔÄÜ£¬½¨ÒéÔÚÄÚ´æÑ¹Á¦½Ï´óʱ¶¨ÆÚµ÷Óᣠ## ʹÓó¡¾° ### 1. ¿çƽ̨·¾¶´¦Àí ```csharp public String GetConfigPath() { if (Runtime.Windows) return @"C:\ProgramData\MyApp\config.json"; else if (Runtime.Linux) return "/etc/myapp/config.json"; else if (Runtime.OSX) return "/Library/Application Support/MyApp/config.json"; else return "config.json"; } ``` ### 2. ÈÝÆ÷»·¾³ÊÊÅä ```csharp public void ConfigureServices() { if (Runtime.Container) { // ÈÝÆ÷»·¾³£º´Ó»·¾³±äÁ¿¶ÁÈ¡ÅäÖà var connStr = Runtime.GetEnvironmentVariable("DATABASE_URL"); services.AddDbContext<MyDbContext>(options => options.UseNpgsql(connStr)); } else { // ±¾µØ¿ª·¢£º´ÓÅäÖÃÎļþ¶ÁÈ¡ var connStr = Configuration.GetConnectionString("Default"); services.AddDbContext<MyDbContext>(options => options.UseNpgsql(connStr)); } } ``` ### 3. ÄÚ´æ¼à¿ØÓëÊÍ·Å ```csharp public class MemoryMonitor { private readonly Timer _timer; private const Int64 MemoryThreshold = 500 * 1024 * 1024; // 500MB public MemoryMonitor() { _timer = new Timer(CheckMemory, null, 0, 30_000); } private void CheckMemory(Object? state) { var gcMemory = GC.GetTotalMemory(false); if (gcMemory > MemoryThreshold) { XTrace.WriteLine($"Äڴ泬¹ýãÐÖµ ({gcMemory / 1024 / 1024}MB)£¬¿ªÊ¼ÊÍ·Å"); Runtime.FreeMemory(); } } } ``` ### 4. ÐÔÄܼÆÊ±Æ÷ ```csharp public class PerformanceTimer : IDisposable { private readonly String _operation; private readonly Int64 _startTime; public PerformanceTimer(String operation) { _operation = operation; _startTime = Runtime.TickCount64; } public void Dispose() { var elapsed = Runtime.TickCount64 - _startTime; XTrace.WriteLine($"{_operation} ºÄʱ: {elapsed}ms"); } } // ʹÓà using (new PerformanceTimer("Êý¾Ý¿â²éѯ")) { var result = db.Query<User>().ToList(); } ``` ## ×î¼Ñʵ¼ù ### 1. Æ½Ì¨ÌØ¶¨´úÂë¸ôÀë ```csharp // ÍÆ¼ö£ºÊ¹ÓÃÌõ¼þÅжϸôÀëÆ½Ì¨ÌØ¶¨´úÂë public void DoWork() { if (Runtime.Windows) DoWorkWindows(); else if (Runtime.Linux) DoWorkLinux(); else DoWorkDefault(); } ``` ### 2. ±ÜÃâÆµ·±µ÷Óà FreeMemory ```csharp // ²»ÍƼö£ºÃ¿´Î²Ù×÷ºó¶¼ÊÍ·Å foreach (var item in items) { ProcessItem(item); Runtime.FreeMemory(); // ÐÔÄÜɱÊÖ£¡ } // ÍÆ¼ö£ºÅúÁ¿´¦ÀíºóÊÍ·Å£¬»ò¶¨Ê±ÊÍ·Å foreach (var item in items) { ProcessItem(item); } Runtime.FreeMemory(); // ´¦ÀíÍê³ÉºóͳһÊÍ·Å ``` ### 3. ʹÓà TickCount64 ¶ø·Ç DateTime ¼ÆÊ± ```csharp // ²»ÍƼö£ºDateTime ¼ÆÊ±¿ÉÄÜÊÜϵͳʱ¼äµ÷ÕûÓ°Ïì var start = DateTime.Now; DoWork(); var elapsed = (DateTime.Now - start).TotalMilliseconds; // ÍÆ¼ö£ºTickCount64 ²»ÊÜϵͳʱ¼äÓ°Ïì var start = Runtime.TickCount64; DoWork(); var elapsed = Runtime.TickCount64 - start; ``` ## Ïà¹ØÁ´½Ó - [»úÆ÷ÐÅÏ¢ MachineInfo](/NewLife/X/Blob/dev/Doc/machine_info-»úÆ÷ÐÅÏ¢MachineInfo.md) - [ÈÕ־ϵͳ ILog](/NewLife/X/Blob/dev/Doc/log-ÈÕÖ¾ILog.md) - [¸ß¼¶¶¨Ê±Æ÷ TimerX](/NewLife/X/Blob/dev/Doc/timerx-¸ß¼¶¶¨Ê±Æ÷TimerX.md)