• 达梦数据库适配ServiceStack框架


    注:达梦的驱动版本请使用2023第四季度及以后版本驱动才可以

    ServiceStack介绍

    ServiceStack官网: https://github.com/ServiceStack/ServiceStack
    ServiceStack是一个开源的十分流行的WebService框架,引用其官网的介绍:“Service Stack is a high-performance .NET web services platform that simplifies the development of high-performance REST (JSON, XML, JSV, HTML, MsgPack, ProtoBuf, CSV) and WCF SOAP Web Services.”
    “ServiceStack是一个高性能的.NET Web Service 平台,他能够简化开发高性能的REST (支持JSON,XML,JSV,HTML,MsgPack,ProtoBuf,CSV等消息格式)以及WCF SOAP风格的WebService”。

    代码段

    sql语句

    CREATE TABLE "SYSDBA"."TestTab"
    (
    "Id" VARCHAR(200) NOT NULL,
    "Name" VARCHAR(200),
    NOT CLUSTER PRIMARY KEY("Id")) STORAGE(ON "MAIN", CLUSTERBTR) ;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Program.cs

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    using NLog;
    using NLog.Web;
    using ServiceStack.DataAnnotations;
    using ServiceStack.OrmLite;
    
    namespace Yidea.Resource.Host
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                var encoding = Encoding.GetEncoding("gb18030");
    
                Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
    
                var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    
    
                var dbFactory = new OrmLiteConnectionFactory("Server=192.15.1.17:5236; UserId=SYSDBA; PWD=SYSDBA; SCHEMA=SYSDBA;", GetSqlDialect());
    
                var Db = dbFactory.CreateDbConnection();
                Db.Open();
                     var aa = Db.Select<TestTab>(o => o.Id == "zzzzzz").First();
                    aa.Name = "xiugai";
                   Db.Save(aa);
    
    
    /*          
               var company = Db.Select().ToList();
               foreach (var item in company)
                {
                    item.Name = item.Name + item.Id;
               }
              Db.SaveAll(company);
    
                //var tab = new TestTab() { Id = "bb", Name = "bbbbbbb" };
                //Db.Save(tab);
    
                List list = Db.Select().ToList();
                foreach (var item in list)
                {
                    item.Name = item.Id + item.Name;
                }
                Db.SaveAll(list);*/
    
    
            }
    
            [Alias("vCompany")]
            public class Company
            {
                [PrimaryKey]
                [AutoIncrement]
                public int Id { get; set; }
                public string Code { get; set; }
                public string Name { get; set; }
                [Alias("EId")]
                public int EnterpriseId { get; set; }
                [Alias("Pid")]
                public int? SuperiorCompanyId { get; set; }
                [Alias("IsDisabled")]
                public bool Disabled { get; set; }
                [Alias("IdPath")]
                public string Hierarchy { get; set; }
            }
    
    
            private static IOrmLiteDialectProvider GetSqlDialect()
            {
                var sqlProvider = new DmaProvider();
                sqlProvider.GetStringConverter().UseUnicode = true;
                sqlProvider.GetDateTimeConverter().DateStyle = DateTimeKind.Local;
                return sqlProvider;
            }
    
            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseUrls("http://*:12345")
                    .UseKestrel(opt =>
                    {
                        opt.AddServerHeader = false;
                        opt.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(5);
                    })
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseIISIntegration()
                    .UseStartup<Startup>()
                    .ConfigureAppConfiguration((builderContext, config) =>
                    {
                        IHostingEnvironment env = builderContext.HostingEnvironment;
    
                        config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
                        config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
                    })
                    .UseNLog();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    DmaProvider.cs

    using Dm;
    using ServiceStack.DataAnnotations;
    using ServiceStack;
    using ServiceStack.OrmLite;
    using ServiceStack.OrmLite.SqlServer.Converters;
    using ServiceStack.OrmLite.SqlServer;
    using ServiceStack.Text;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using System.Data.SqlClient;
    using System.IO;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using ServiceStack.Data;
    using System.Collections;
    
    namespace Yidea.Resource.Host
    {
        public class DmaProvider : OrmLiteDialectProviderBase<DmaProvider>
        {
            public static DmaProvider Instance = new();
    
            public DmaProvider()
            {
                base.AutoIncrementDefinition = "IDENTITY(1,1)";
                base.SelectIdentitySql = "SELECT SCOPE_IDENTITY()";
    
                base.InitColumnTypeMap();
    
                RowVersionConverter = new SqlServerRowVersionConverter();
    
                base.RegisterConverter<string>(new SqlServerStringConverter());
                base.RegisterConverter<bool>(new SqlServerBoolConverter());
    
                base.RegisterConverter<sbyte>(new SqlServerSByteConverter());
                base.RegisterConverter<ushort>(new SqlServerUInt16Converter());
                base.RegisterConverter<uint>(new SqlServerUInt32Converter());
                base.RegisterConverter<ulong>(new SqlServerUInt64Converter());
    
                base.RegisterConverter<float>(new SqlServerFloatConverter());
                base.RegisterConverter<double>(new SqlServerDoubleConverter());
                base.RegisterConverter<decimal>(new SqlServerDecimalConverter());
    
                base.RegisterConverter<DateTime>(new SqlServerDateTimeConverter());
    
                base.RegisterConverter<Guid>(new SqlServerGuidConverter());
    
                base.RegisterConverter<byte[]>(new SqlServerByteArrayConverter());
    
                this.Variables = new Dictionary<string, string>
                {
                    { OrmLiteVariables.SystemUtc, "SYSUTCDATETIME()" },
                    { OrmLiteVariables.MaxText, "VARCHAR(MAX)" },
                    { OrmLiteVariables.MaxTextUnicode, "NVARCHAR(MAX)" },
                    { OrmLiteVariables.True, SqlBool(true) },
                    { OrmLiteVariables.False, SqlBool(false) },
                };
            }
    
            public override string GetQuotedValue(string paramValue)
            {
                return (StringConverter.UseUnicode ? "N'" : "'") + paramValue.Replace("'", "''") + "'";
            }
    
            public override IDbConnection CreateConnection(string connectionString, Dictionary<string, string> options)
            {
                DmConnection conn = new DmConnection();
                conn.ConnectionString = connectionString;
                return conn;
            }
    
            public override SqlExpression<T> SqlExpression<T>() => new SqlServerExpression<T>(this);
    
           // public override IDbDataParameter CreateParam() => new SqlParameter();
            public override IDbDataParameter CreateParam() => new DmParameter();
    
            private const string DefaultSchema = "dbo";
            public override string ToTableNamesStatement(string schema)
            {
                var sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'";
                return sql + " AND TABLE_SCHEMA = {0}".SqlFmt(this, schema ?? DefaultSchema);
            }
    
            public override string ToTableNamesWithRowCountsStatement(bool live, string schema)
            {
                var schemaSql = " AND s.Name = {0}".SqlFmt(this, schema ?? DefaultSchema);
    
                var sql = @"SELECT t.NAME, p.rows FROM sys.tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id 
                                   INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id 
                                   INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
                             WHERE t.is_ms_shipped = 0 " + schemaSql + " GROUP BY t.NAME, p.Rows";
                return sql;
            }
    
            //public override List GetSchemas(IDbCommand dbCmd)
            //{
            //    var sql = "SELECT DISTINCT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'";
            //    return dbCmd.SqlColumn(sql);
            //}
    
            //public override Dictionary> GetSchemaTables(IDbCommand dbCmd)
            //{
            //    var sql = "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'";
            //    return dbCmd.Lookup(sql);
            //}
    
            public override bool DoesSchemaExist(IDbCommand dbCmd, string schemaName)
            {
                var sql = $"SELECT count(*) FROM sys.schemas WHERE name = '{schemaName.SqlParam()}'";
                var result = dbCmd.ExecLongScalar(sql);
                return result > 0;
            }
    
            //public override async Task DoesSchemaExistAsync(IDbCommand dbCmd, string schemaName, CancellationToken token = default)
            //{
            //    var sql = $"SELECT count(*) FROM sys.schemas WHERE name = '{schemaName.SqlParam()}'";
            //    var result = await dbCmd.ExecLongScalarAsync(sql, token);
            //    return result > 0;
            //}
    
            public override string ToCreateSchemaStatement(string schemaName)
            {
                var sql = $"CREATE SCHEMA [{GetSchemaName(schemaName)}]";
                return sql;
            }
    
            //public override string ToCreateSavePoint(string name) => $"SAVE TRANSACTION {name}";
            //public override string ToReleaseSavePoint(string name) => null;
            //public override string ToRollbackSavePoint(string name) => $"ROLLBACK TRANSACTION {name}";
    
            public override bool DoesTableExist(IDbCommand dbCmd, string tableName, string schema = null)
            {
                var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = {0}"
                    .SqlFmt(this, tableName);
    
                if (schema != null)
                    sql += " AND TABLE_SCHEMA = {0}".SqlFmt(this, schema);
                else
                    sql += " AND TABLE_SCHEMA <> 'Security'";
    
                var result = dbCmd.ExecLongScalar(sql);
    
                return result > 0;
            }
    
            //public override async Task DoesTableExistAsync(IDbCommand dbCmd, string tableName, string schema = null, CancellationToken token = default)
            //{
            //    var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = {0}"
            //        .SqlFmt(this, tableName);
    
            //    if (schema != null)
            //        sql += " AND TABLE_SCHEMA = {0}".SqlFmt(this, schema);
            //    else
            //        sql += " AND TABLE_SCHEMA <> 'Security'";
    
            //    var result = await dbCmd.ExecLongScalarAsync(sql, token);
    
            //    return result > 0;
            //}
    
            public override bool DoesColumnExist(IDbConnection db, string columnName, string tableName, string schema = null)
            {
                var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = @columnName"
                    .SqlFmt(this, tableName, columnName);
    
                if (schema != null)
                    sql += " AND TABLE_SCHEMA = @schema";
    
                var result = db.SqlScalar<long>(sql, new { tableName, columnName, schema });
    
                return result > 0;
            }
    
            //public override async Task DoesColumnExistAsync(IDbConnection db, string columnName, string tableName, string schema = null,
            //    CancellationToken token = default)
            //{
            //    var sql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tableName AND COLUMN_NAME = @columnName"
            //        .SqlFmt(this, tableName, columnName);
    
            //    if (schema != null)
            //        sql += " AND TABLE_SCHEMA = @schema";
    
            //    var result = await db.SqlScalarAsync(sql, new { tableName, columnName, schema }, token: token);
    
            //    return result > 0;
            //}
    
            //public override string GetForeignKeyOnDeleteClause(ForeignKeyConstraint foreignKey)
            //{
            //    return "RESTRICT" == (foreignKey.OnDelete ?? "").ToUpper()
            //        ? ""
            //        : base.GetForeignKeyOnDeleteClause(foreignKey);
            //}
    
            //public override string GetForeignKeyOnUpdateClause(ForeignKeyConstraint foreignKey)
            //{
            //    return "RESTRICT" == (foreignKey.OnUpdate ?? "").ToUpper()
            //        ? ""
            //        : base.GetForeignKeyOnUpdateClause(foreignKey);
            //}
    
            public override string GetDropForeignKeyConstraints(ModelDefinition modelDef)
            {
                //TODO: find out if this should go in base class?
    
                var sb = StringBuilderCache.Allocate();
                foreach (var fieldDef in modelDef.FieldDefinitions)
                {
                    if (fieldDef.ForeignKey != null)
                    {
                        var foreignKeyName = fieldDef.ForeignKey.GetForeignKeyName(
                            modelDef,
                            OrmLiteUtils.GetModelDefinition(fieldDef.ForeignKey.ReferenceType),
                            NamingStrategy,
                            fieldDef);
    
                        var tableName = GetQuotedTableName(modelDef);
                        sb.AppendLine($"IF EXISTS (SELECT name FROM sys.foreign_keys WHERE name = '{foreignKeyName}')");
                        sb.AppendLine("BEGIN");
                        sb.AppendLine($"  ALTER TABLE {tableName} DROP {foreignKeyName};");
                        sb.AppendLine("END");
                    }
                }
    
                return StringBuilderCache.ReturnAndFree(sb);
            }
    
            //public override string ToAddColumnStatement(string schema, string table, FieldDefinition fieldDef) =>
            //    $"ALTER TABLE {GetQuotedTableName(table, schema)} ADD {GetColumnDefinition(fieldDef)};";
    
            //public override string ToAlterColumnStatement(string schema, string table, FieldDefinition fieldDef) =>
            //    $"ALTER TABLE {GetQuotedTableName(table, schema)} ALTER COLUMN {GetColumnDefinition(fieldDef)};";
    
            //public override string ToChangeColumnNameStatement(string schema, string table, FieldDefinition fieldDef, string oldColumn)
            //{
            //    var modelName = NamingStrategy.GetTableName(table);
            //    var objectName = $"{modelName}.{oldColumn}";
            //    return $"EXEC sp_rename {GetQuotedValue(objectName)}, {GetQuotedValue(fieldDef.FieldName)}, {GetQuotedValue("COLUMN")};";
            //}
    
            //public override string ToRenameColumnStatement(string schema, string table, string oldColumn, string newColumn)
            //{
            //    var modelName = NamingStrategy.GetTableName(table);
            //    var objectName = $"{modelName}.{GetQuotedColumnName(oldColumn)}";
            //    return $"EXEC sp_rename {GetQuotedValue(objectName)}, {GetQuotedColumnName(newColumn)}, 'COLUMN';";
            //}
    
            protected virtual string GetAutoIncrementDefinition(FieldDefinition fieldDef)
            {
                return AutoIncrementDefinition;
            }
    
            public override string GetAutoIdDefaultValue(FieldDefinition fieldDef)
            {
                return fieldDef.FieldType == typeof(Guid)
                    ? "newid()"
                    : null;
            }
    
            public override string GetColumnDefinition(FieldDefinition fieldDef)
            {
                // https://msdn.microsoft.com/en-us/library/ms182776.aspx
                if (fieldDef.IsRowVersion)
                    return $"{fieldDef.FieldName} rowversion NOT NULL";
    
                var fieldDefinition = ResolveFragment(fieldDef.CustomFieldDefinition) ??
                    GetColumnTypeDefinition(fieldDef.ColumnType, fieldDef.FieldLength, fieldDef.Scale);
    
                var sql = StringBuilderCache.Allocate();
                sql.Append($"{GetQuotedColumnName(fieldDef.FieldName)} {fieldDefinition}");
    
                if (fieldDef.FieldType == typeof(string))
                {
                    // https://msdn.microsoft.com/en-us/library/ms184391.aspx
                    var collation = fieldDef.PropertyInfo?.FirstAttribute<SqlServerCollateAttribute>()?.Collation;
                    if (!string.IsNullOrEmpty(collation))
                    {
                        sql.Append($" COLLATE {collation}");
                    }
                }
    
                if (fieldDef.IsPrimaryKey)
                {
                    sql.Append(" PRIMARY KEY");
    
                    if (fieldDef.IsNonClustered)
                        sql.Append(" NONCLUSTERED");
    
                    if (fieldDef.AutoIncrement)
                    {
                        sql.Append(" ").Append(GetAutoIncrementDefinition(fieldDef));
                    }
                }
                else
                {
                    sql.Append(fieldDef.IsNullable ? " NULL" : " NOT NULL");
                }
    
                if (fieldDef.IsUniqueConstraint)
                {
                    sql.Append(" UNIQUE");
                }
    
                var defaultValue = GetDefaultValue(fieldDef);
                if (!string.IsNullOrEmpty(defaultValue))
                {
                    sql.AppendFormat(DefaultValueFormat, defaultValue);
                }
    
                return StringBuilderCache.ReturnAndFree(sql);
            }
    
            //public override void BulkInsert(IDbConnection db, IEnumerable objs, BulkInsertConfig config = null)
            //{
            //    config ??= new();
            //    //if (config.Mode == BulkInsertMode.Sql)
            //    //{
            //    //    base.BulkInsert(db, objs, config);
            //    //    return;
            //    //}
    
            //    var sqlConn = (SqlConnection)db.ToDbConnection();
            //    using var bulkCopy = new SqlBulkCopy(sqlConn);
            //    var modelDef = ModelDefinition.Definition;
    
            //    bulkCopy.BatchSize = config.BatchSize;
            //    bulkCopy.DestinationTableName = modelDef.ModelName;
    
            //    var table = new DataTable();
            //    var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields: config.InsertFields);
            //    foreach (var fieldDef in fieldDefs)
            //    {
            //        if (ShouldSkipInsert(fieldDef) && !fieldDef.AutoId)
            //            continue;
    
            //        var columnName = NamingStrategy.GetColumnName(fieldDef.FieldName);
            //        bulkCopy.ColumnMappings.Add(columnName, columnName);
    
            //        var converter = GetConverterBestMatch(fieldDef);
            //        var colType = converter.DbType switch
            //        {
            //            DbType.String => typeof(string),
            //            DbType.Int32 => typeof(int),
            //            DbType.Int64 => typeof(long),
            //            _ => Nullable.GetUnderlyingType(fieldDef.FieldType) ?? fieldDef.FieldType
            //        };
    
            //        table.Columns.Add(columnName, colType);
            //    }
    
            //    foreach (var obj in objs)
            //    {
            //        var row = table.NewRow();
            //        foreach (var fieldDef in fieldDefs)
            //        {
            //            if (ShouldSkipInsert(fieldDef) && !fieldDef.AutoId)
            //                continue;
    
            //            var value = fieldDef.AutoId
            //                ? GetInsertDefaultValue(fieldDef)
            //                : fieldDef.GetValue(obj);
    
            //            var converter = GetConverterBestMatch(fieldDef);
            //            var dbValue = converter.ToDbValue(fieldDef.FieldType, value);
            //            var columnName = NamingStrategy.GetColumnName(fieldDef.FieldName);
            //            dbValue ??= DBNull.Value;
            //            row[columnName] = dbValue;
            //        }
            //        table.Rows.Add(row);
            //    }
    
            //    bulkCopy.WriteToServer(table);
            //}
    
            public override string ToInsertRowStatement(IDbCommand cmd, object objWithProperties, ICollection<string> insertFields = null)
            {
                var sbColumnNames = StringBuilderCache.Allocate();
                var sbColumnValues = StringBuilderCacheAlt.Allocate();
                var sbReturningColumns = StringBuilderCacheAlt.Allocate();
                var tableType = objWithProperties.GetType();
                var modelDef = GetModel(tableType);
    
                var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields);
                foreach (var fieldDef in fieldDefs)
                {
                    if (ShouldReturnOnInsert(modelDef, fieldDef))
                    {
                        if (sbReturningColumns.Length > 0)
                            sbReturningColumns.Append(",");
                        sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
                    }
    
                    if (ShouldSkipInsert(fieldDef) && !fieldDef.AutoId)
                        continue;
    
                    if (sbColumnNames.Length > 0)
                        sbColumnNames.Append(",");
                    if (sbColumnValues.Length > 0)
                        sbColumnValues.Append(",");
    
                    try
                    {
                        sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName));
                        sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)));
    
                        AddParameter(cmd, fieldDef);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("ERROR in ToInsertRowStatement(): " + ex.Message, ex);
                        throw;
                    }
                }
    
                foreach (var fieldDef in modelDef.AutoIdFields) // need to include any AutoId fields that weren't included 
                {
                    if (fieldDefs.Contains(fieldDef))
                        continue;
    
                    if (sbReturningColumns.Length > 0)
                        sbReturningColumns.Append(",");
                    sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
                }
    
                var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns);
                strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : "";
                var sql = sbColumnNames.Length > 0
                    ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) " +
                      strReturning +
                      $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"
                    : $"INSERT INTO {GetQuotedTableName(modelDef)} {strReturning} DEFAULT VALUES";
    
                return sql;
            }
    
            protected string Sequence(string schema, string sequence)
            {
                if (schema == null)
                    return GetQuotedName(sequence);
    
                var escapedSchema = NamingStrategy.GetSchemaName(schema)
                    .Replace(".", "\".\"");
    
                return GetQuotedName(escapedSchema)
                       + "."
                       + GetQuotedName(sequence);
            }
    
            protected override bool ShouldSkipInsert(FieldDefinition fieldDef) =>
                fieldDef.ShouldSkipInsert() || fieldDef.AutoId;
    
            protected virtual bool ShouldReturnOnInsert(ModelDefinition modelDef, FieldDefinition fieldDef) =>
                fieldDef.ReturnOnInsert || (fieldDef.IsPrimaryKey && fieldDef.AutoIncrement && HasInsertReturnValues(modelDef)) || fieldDef.AutoId;
    
            public override bool HasInsertReturnValues(ModelDefinition modelDef) =>
                modelDef.FieldDefinitions.Any(x => x.ReturnOnInsert || (x.AutoId && x.FieldType == typeof(Guid)));
    
            protected virtual bool SupportsSequences(FieldDefinition fieldDef) => false;
    
            //public override void EnableIdentityInsert(IDbCommand cmd)
            //{
            //    var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition);
            //    cmd.ExecNonQuery($"SET IDENTITY_INSERT {tableName} ON");
            //}
    
            //public override Task EnableIdentityInsertAsync(IDbCommand cmd, CancellationToken token = default)
            //{
            //    var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition);
            //    return cmd.ExecNonQueryAsync($"SET IDENTITY_INSERT {tableName} ON", null, token);
            //}
    
            //public override void DisableIdentityInsert(IDbCommand cmd)
            //{
            //    var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition);
            //    cmd.ExecNonQuery($"SET IDENTITY_INSERT {tableName} OFF");
            //}
    
            //public override Task DisableIdentityInsertAsync(IDbCommand cmd, CancellationToken token = default)
            //{
            //    var tableName = cmd.GetDialectProvider().GetQuotedTableName(ModelDefinition.Definition);
            //    return cmd.ExecNonQueryAsync($"SET IDENTITY_INSERT {tableName} OFF", null, token);
            //}
    
            public override bool PrepareParameterizedUpdateStatement<T>(IDbCommand cmd, ICollection<string> updateFields = null)
            {
                var sql = StringBuilderCache.Allocate();
                var sqlFilter = StringBuilderCacheAlt.Allocate();
                var modelDef = ModelDefinition<T>.Definition;
                var hadRowVersion = false;
                var updateAllFields = updateFields == null || updateFields.Count == 0;
    
                cmd.Parameters.Clear();
    
                foreach (var fieldDef in modelDef.FieldDefinitions)
                {
                    if (fieldDef.ShouldSkipUpdate())
                        continue;
    
                    try
                    {
                        if ((fieldDef.IsPrimaryKey || fieldDef.IsRowVersion) && updateAllFields)
                        {
                            if (sqlFilter.Length > 0)
                                sqlFilter.Append(" AND ");
    
                            AppendFieldCondition(sqlFilter, fieldDef, cmd);
    
                            if (fieldDef.IsRowVersion)
                                hadRowVersion = true;
    
                            continue;
                        }
    
                        if (!updateAllFields && !updateFields.Contains(fieldDef.Name, StringComparer.OrdinalIgnoreCase))
                            continue;
    
                        if (sql.Length > 0)
                            sql.Append(", ");
    
                        sql
                            .Append(GetQuotedColumnName(fieldDef.FieldName))
                            .Append("=")
                            .Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)));
    
                        AddParameter(cmd, fieldDef);
                    }
                    catch (Exception ex)
                    {
                        OrmLiteUtils.HandleException(ex, "ERROR in PrepareParameterizedUpdateStatement(): " + ex.Message);
                    }
                }
    
                if (sql.Length > 0)
                {
                    var strFilter = StringBuilderCacheAlt.ReturnAndFree(sqlFilter);
                    cmd.CommandText = $"UPDATE {GetQuotedTableName(modelDef)} " +
                                      $"SET {StringBuilderCache.ReturnAndFree(sql)} {(strFilter.Length > 0 ? "WHERE " + strFilter : "")}";
                    cmd.CommandText = cmd.CommandText.ReplaceAll("@", ":");
                }
                else
                {
                    cmd.CommandText = "";
                }
    
                return hadRowVersion;
            }
            public void SetValue(object instance, object value)
            {
                if (instance is IDictionary d)
                {
                    d[Name] = value;
                    return;
                }
    
                this.SetValueFn?.Invoke(instance, value);
            }
    
    
            public string Name { get; set; }
            public SetMemberDelegate SetValueFn { get; set; }
            public override void SetParameterValues<T>(IDbCommand dbCmd, object obj)
            {
                var modelDef = GetModel(typeof(T));
                var fieldMap = GetFieldDefinitionMap(modelDef);
    
                foreach (IDataParameter p in dbCmd.Parameters)
                {
                    var fieldName = this.ToFieldName(p.ParameterName);
                    fieldMap.TryGetValue(fieldName, out var fieldDef);
    
                    if (fieldDef == null)
                    {
                        if (ParamNameFilter != null)
                        {
                            fieldDef = modelDef.GetFieldDefinition(name =>
                                string.Equals(ParamNameFilter(name), fieldName, StringComparison.OrdinalIgnoreCase));
                        }
    
                        if (fieldDef == null)
                            throw new ArgumentException($"Field Definition '{fieldName}' was not found");
                    }
    
                    if (fieldDef.AutoId && p.Value != null)
                    {
                        var existingId = fieldDef.GetValue(obj);
                        if (existingId is Guid existingGuid && existingGuid != default(Guid))
                        {
                            p.Value = existingGuid; // Use existing value if not default
                        }
    
                        //fieldDef.SetValue(obj, p.Value); //Auto populate default values
                        continue;
                    }
    
                    SetParameterValue(fieldDef, p, obj);
                }
                dbCmd.CommandText = dbCmd.CommandText.ReplaceAll("@", ":");
                var rowsUpdated = dbCmd.ExecNonQuery();
            }
    
    
            public virtual void SetParameterValue(FieldDefinition fieldDef, IDataParameter p, object obj)
            {
                var value = GetValueOrDbNull(fieldDef, obj);
                p.Value = value;
    
                SetParameterSize(fieldDef, p);
            }
    
            protected virtual void SetParameterSize(FieldDefinition fieldDef, IDataParameter p)
            {
                if (p.Value is string s && p is IDbDataParameter dataParam && dataParam.Size > 0 && s.Length > dataParam.Size)
                {
                    // db param Size set in StringConverter
                    dataParam.Size = s.Length;
                }
            }
    
            protected virtual object GetValue(FieldDefinition fieldDef, object obj)
            {
                return GetFieldValue(fieldDef, fieldDef.GetValue(obj));
            }
    
            public object GetFieldValue(FieldDefinition fieldDef, object value)
            {
                if (value == null)
                    return null;
    
                var converter = GetConverterBestMatch(fieldDef);
                try
                {
                    return converter.ToDbValue(fieldDef.FieldType, value);
                }
                catch (Exception ex)
                {
                    Log.Error($"Error in {converter.GetType().Name}.ToDbValue() for field '{fieldDef.Name}' of Type '{fieldDef.FieldType}' with value '{value.GetType().Name}'", ex);
                    throw;
                }
            }
    
            public object GetFieldValue(Type fieldType, object value)
            {
                if (value == null)
                    return null;
    
                var converter = GetConverterBestMatch(fieldType);
                try
                {
                    return converter.ToDbValue(fieldType, value);
                }
                catch (Exception ex)
                {
                    Log.Error($"Error in {converter.GetType().Name}.ToDbValue() for field of Type '{fieldType}' with value '{value.GetType().Name}'", ex);
                    throw;
                }
            }
    
            protected virtual object GetValueOrDbNull(FieldDefinition fieldDef, object obj)
            {
                var value = GetValue(fieldDef, obj);
                if (value == null)
                    return DBNull.Value;
    
                return value;
            }
    
            protected virtual object GetQuotedValueOrDbNull<T>(FieldDefinition fieldDef, object obj)
            {
                var value = fieldDef.GetValue(obj);
    
                if (value == null)
                    return DBNull.Value;
    
                var unquotedVal = GetQuotedValue(value, fieldDef.FieldType)
                    .TrimStart('\'').TrimEnd('\''); ;
    
                if (string.IsNullOrEmpty(unquotedVal))
                    return DBNull.Value;
    
                return unquotedVal;
            }
    
            public override string ToUpdateStatement<T>(IDbCommand dbCmd, T item, ICollection<string> updateFields = null)
            {
                return base.ToUpdateStatement(dbCmd, item, updateFields);
            }
            public override void PrepareParameterizedInsertStatement<T>(IDbCommand cmd, ICollection<string> insertFields = null)
            {
                var sbColumnNames = StringBuilderCache.Allocate();
                var sbColumnValues = StringBuilderCacheAlt.Allocate();
                var sbReturningColumns = StringBuilderCacheAlt.Allocate();
                var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T));
    
                cmd.Parameters.Clear();
    
                var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields);
                foreach (var fieldDef in fieldDefs)
                {
                    if (ShouldReturnOnInsert(modelDef, fieldDef))
                    {
                        if (sbReturningColumns.Length > 0)
                            sbReturningColumns.Append(",");
                        sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
                    }
    
                    if ((ShouldSkipInsert(fieldDef) && !fieldDef.AutoId))
                        continue;
    
                    if (sbColumnNames.Length > 0)
                        sbColumnNames.Append(",");
                    if (sbColumnValues.Length > 0)
                        sbColumnValues.Append(",");
    
                    try
                    {
                        sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName));
    
                        if (SupportsSequences(fieldDef))
                        {
                            sbColumnValues.Append("NEXT VALUE FOR " + Sequence(NamingStrategy.GetSchemaName(modelDef), fieldDef.Sequence));
                        }
                        else
                        {
                            sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName)));
                            AddParameter(cmd, fieldDef);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex);
                        throw;
                    }
                }
    
                foreach (var fieldDef in modelDef.AutoIdFields) // need to include any AutoId fields that weren't included 
                {
                    if (fieldDefs.Contains(fieldDef))
                        continue;
    
                    if (sbReturningColumns.Length > 0)
                        sbReturningColumns.Append(",");
                    sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
                }
    
                var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns);
                strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : "";
                cmd.CommandText = sbColumnNames.Length > 0
                    ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) {strReturning}" +
                      $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"
                    : $"INSERT INTO {GetQuotedTableName(modelDef)}{strReturning} DEFAULT VALUES";
                cmd.CommandText = cmd.CommandText.ReplaceAll("@", ":");
            }
            //public override void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null,
            //    Func shouldInclude = null)
            //{
            //    var sbColumnNames = StringBuilderCache.Allocate();
            //    var sbColumnValues = StringBuilderCacheAlt.Allocate();
            //    var sbReturningColumns = StringBuilderCacheAlt.Allocate();
            //    var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T));
    
            //    cmd.Parameters.Clear();
    
            //    var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields);
            //    foreach (var fieldDef in fieldDefs)
            //    {
            //        if (ShouldReturnOnInsert(modelDef, fieldDef))
            //        {
            //            if (sbReturningColumns.Length > 0)
            //                sbReturningColumns.Append(",");
            //            sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
            //        }
    
            //        if ((ShouldSkipInsert(fieldDef) && !fieldDef.AutoId)
            //            && shouldInclude?.Invoke(fieldDef) != true)
            //            continue;
    
            //        if (sbColumnNames.Length > 0)
            //            sbColumnNames.Append(",");
            //        if (sbColumnValues.Length > 0)
            //            sbColumnValues.Append(",");
    
            //        try
            //        {
            //            sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName));
    
            //            if (SupportsSequences(fieldDef))
            //            {
            //                sbColumnValues.Append("NEXT VALUE FOR " + Sequence(NamingStrategy.GetSchemaName(modelDef), fieldDef.Sequence));
            //            }
            //            else
            //            {
            //                sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName), fieldDef.CustomInsert));
            //                AddParameter(cmd, fieldDef);
            //            }
            //        }
            //        catch (Exception ex)
            //        {
            //            Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex);
            //            throw;
            //        }
            //    }
    
            //    foreach (var fieldDef in modelDef.AutoIdFields) // need to include any AutoId fields that weren't included 
            //    {
            //        if (fieldDefs.Contains(fieldDef))
            //            continue;
    
            //        if (sbReturningColumns.Length > 0)
            //            sbReturningColumns.Append(",");
            //        sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
            //    }
    
            //    var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns);
            //    strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : "";
            //    cmd.CommandText = sbColumnNames.Length > 0
            //        ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) {strReturning}" +
            //          $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"
            //        : $"INSERT INTO {GetQuotedTableName(modelDef)}{strReturning} DEFAULT VALUES";
            //}
            //public override void PrepareParameterizedInsertStatement(IDbCommand cmd, ICollection insertFields = null,
            //    Func shouldInclude = null)
            //{
            //    var sbColumnNames = StringBuilderCache.Allocate();
            //    var sbColumnValues = StringBuilderCacheAlt.Allocate();
            //    var sbReturningColumns = StringBuilderCacheAlt.Allocate();
            //    var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T));
    
            //    cmd.Parameters.Clear();
    
            //    var fieldDefs = GetInsertFieldDefinitions(modelDef, insertFields);
            //    foreach (var fieldDef in fieldDefs)
            //    {
            //        if (ShouldReturnOnInsert(modelDef, fieldDef))
            //        {
            //            if (sbReturningColumns.Length > 0)
            //                sbReturningColumns.Append(",");
            //            sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
            //        }
    
            //        if ((ShouldSkipInsert(fieldDef) && !fieldDef.AutoId)
            //            && shouldInclude?.Invoke(fieldDef) != true)
            //            continue;
    
            //        if (sbColumnNames.Length > 0)
            //            sbColumnNames.Append(",");
            //        if (sbColumnValues.Length > 0)
            //            sbColumnValues.Append(",");
    
            //        try
            //        {
            //            sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName));
    
            //            if (SupportsSequences(fieldDef))
            //            {
            //                sbColumnValues.Append("NEXT VALUE FOR " + Sequence(NamingStrategy.GetSchemaName(modelDef), fieldDef.Sequence));
            //            }
            //            else
            //            {
            //                sbColumnValues.Append(this.GetParam(SanitizeFieldNameForParamName(fieldDef.FieldName), fieldDef.CustomInsert));
            //                AddParameter(cmd, fieldDef);
            //            }
            //        }
            //        catch (Exception ex)
            //        {
            //            Log.Error("ERROR in PrepareParameterizedInsertStatement(): " + ex.Message, ex);
            //            throw;
            //        }
            //    }
    
            //    foreach (var fieldDef in modelDef.AutoIdFields) // need to include any AutoId fields that weren't included 
            //    {
            //        if (fieldDefs.Contains(fieldDef))
            //            continue;
    
            //        if (sbReturningColumns.Length > 0)
            //            sbReturningColumns.Append(",");
            //        sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
            //    }
    
            //    var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns);
            //    strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : "";
            //    cmd.CommandText = sbColumnNames.Length > 0
            //        ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) {strReturning}" +
            //          $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"
            //        : $"INSERT INTO {GetQuotedTableName(modelDef)}{strReturning} DEFAULT VALUES";
            //}
    
            public override void PrepareInsertRowStatement<T>(IDbCommand dbCmd, Dictionary<string, object> args)
            {
                var sbColumnNames = StringBuilderCache.Allocate();
                var sbColumnValues = StringBuilderCacheAlt.Allocate();
                var sbReturningColumns = StringBuilderCacheAlt.Allocate();
                var modelDef = OrmLiteUtils.GetModelDefinition(typeof(T));
    
                dbCmd.Parameters.Clear();
    
                //foreach (var entry in args)
                //{
                //    var fieldDef = modelDef.AssertFieldDefinition(entry.Key);
    
                //    if (ShouldReturnOnInsert(modelDef, fieldDef))
                //    {
                //        if (sbReturningColumns.Length > 0)
                //            sbReturningColumns.Append(",");
                //        sbReturningColumns.Append("INSERTED." + GetQuotedColumnName(fieldDef.FieldName));
                //    }
    
                //    if (ShouldSkipInsert(fieldDef) && !fieldDef.AutoId)
                //        continue;
    
                //    var value = entry.Value;
    
                //    if (sbColumnNames.Length > 0)
                //        sbColumnNames.Append(",");
                //    if (sbColumnValues.Length > 0)
                //        sbColumnValues.Append(",");
    
                //    try
                //    {
                //        sbColumnNames.Append(GetQuotedColumnName(fieldDef.FieldName));
                //        sbColumnValues.Append(this.GetInsertParam(dbCmd, value, fieldDef));
                //    }
                //    catch (Exception ex)
                //    {
                //        Log.Error("ERROR in PrepareInsertRowStatement(): " + ex.Message, ex);
                //        throw;
                //    }
                //}
    
                //var strReturning = StringBuilderCacheAlt.ReturnAndFree(sbReturningColumns);
                //strReturning = strReturning.Length > 0 ? "OUTPUT " + strReturning + " " : "";
                //dbCmd.CommandText = sbColumnNames.Length > 0
                //    ? $"INSERT INTO {GetQuotedTableName(modelDef)} ({StringBuilderCache.ReturnAndFree(sbColumnNames)}) {strReturning}" +
                //      $"VALUES ({StringBuilderCacheAlt.ReturnAndFree(sbColumnValues)})"
                //    : $"INSERT INTO {GetQuotedTableName(modelDef)} {strReturning}DEFAULT VALUES";
            }
            public enum QueryType
            {
                Select,
                Single,
                Scalar,
            }
            public override FieldDefinition[] GetInsertFieldDefinitions(ModelDefinition modelDef, ICollection<string> insertFields)
            {
                return base.GetInsertFieldDefinitions(modelDef, insertFields);
            }
            protected override object GetInsertDefaultValue(FieldDefinition fieldDef)
            {
                return base.GetInsertDefaultValue(fieldDef);
            }
            public override string ToInsertStatement<T>(IDbCommand dbCmd, T item, ICollection<string> insertFields = null)
            {
                return base.ToInsertStatement(dbCmd, item, insertFields);
            }
            public override string ToSelectStatement(Type tableType, string sqlFilter, params object[] filterParams)
            {
                var aa = base.ToSelectStatement(tableType, sqlFilter, filterParams).ReplaceAll("@", ":");
                return aa;
            }
            public override string ToSelectStatement(ModelDefinition modelDef, string selectExpression, string bodyExpression, string orderByExpression = null, int? offset = null, int? rows = null)
            {
                var aa = base.ToSelectStatement(modelDef, selectExpression, bodyExpression, orderByExpression, offset, rows).ReplaceAll("@", ":");
                return aa;
            }
            //public override string ToSelectStatement(QueryType queryType, ModelDefinition modelDef,
            //    string selectExpression,
            //    string bodyExpression,
            //    string orderByExpression = null,
            //    int? offset = null,
            //    int? rows = null,
            //    ISet tags = null)
            //{
            //    var sb = StringBuilderCache.Allocate();
            //    ApplyTags(sb, tags);
    
            //    sb.Append(selectExpression)
            //    .Append(bodyExpression);
    
            //    if (!offset.HasValue && !rows.HasValue || (queryType != QueryType.Select && rows != 1))
            //        return StringBuilderCache.ReturnAndFree(sb) + orderByExpression;
    
            //    if (offset is < 0)
            //        throw new ArgumentException($"Skip value:'{offset.Value}' must be>=0");
    
            //    if (rows is < 0)
            //        throw new ArgumentException($"Rows value:'{rows.Value}' must be>=0");
    
            //    var skip = offset ?? 0;
            //    var take = rows ?? int.MaxValue;
    
            //    var selectType = selectExpression.StartsWithIgnoreCase("SELECT DISTINCT") ? "SELECT DISTINCT" : "SELECT";
    
            //    //avoid Windowing function if unnecessary
            //    if (skip == 0)
            //    {
            //        var sql = StringBuilderCache.ReturnAndFree(sb) + orderByExpression;
            //        return SqlTop(sql, take, selectType);
            //    }
    
            //    // Required because ordering is done by Windowing function
            //    if (string.IsNullOrEmpty(orderByExpression))
            //    {
            //        if (modelDef.PrimaryKey == null)
            //            throw new ApplicationException("Malformed model, no PrimaryKey defined");
    
            //        orderByExpression = $"ORDER BY {this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey)}";
            //    }
    
            //    var row = take == int.MaxValue ? take : skip + take;
    
            //    var ret = $"SELECT * FROM (SELECT {selectExpression.Substring(selectType.Length)}, ROW_NUMBER() OVER ({orderByExpression}) As RowNum {bodyExpression}) AS RowConstrainedResult WHERE RowNum > {skip} AND RowNum <= {row}";
    
            //    return ret;
            //}
    
            protected static string SqlTop(string sql, int take, string selectType = null)
            {
                selectType ??= sql.StartsWithIgnoreCase("SELECT DISTINCT") ? "SELECT DISTINCT" : "SELECT";
    
                if (take == int.MaxValue)
                    return sql;
    
                if (sql.Length < "SELECT".Length)
                    return sql;
    
                return sql.Substring(0, sql.IndexOf(selectType)) + selectType + " TOP " + take + sql.Substring(sql.IndexOf(selectType) + selectType.Length);
            }
    
            //SELECT without RowNum and prefer aliases to be able to use in SELECT IN () Reference Queries
            public static string UseAliasesOrStripTablePrefixes(string selectExpression)
            {
                if (selectExpression.IndexOf('.') < 0)
                    return selectExpression;
    
                var sb = StringBuilderCache.Allocate();
                var selectToken = selectExpression.SplitOnFirst(' ');
                var tokens = selectToken[1].Split(',');
                foreach (var token in tokens)
                {
                    if (sb.Length > 0)
                        sb.Append(", ");
    
                    var field = token.Trim();
    
                    var aliasParts = field.SplitOnLast(' ');
                    if (aliasParts.Length > 1)
                    {
                        sb.Append(" " + aliasParts[aliasParts.Length - 1]);
                        continue;
                    }
    
                    var parts = field.SplitOnLast('.');
                    if (parts.Length > 1)
                    {
                        sb.Append(" " + parts[parts.Length - 1]);
                    }
                    else
                    {
                        sb.Append(" " + field);
                    }
                }
    
                var sqlSelect = selectToken[0] + " " + StringBuilderCache.ReturnAndFree(sb).Trim();
                return sqlSelect;
            }
    
            public override string GetLoadChildrenSubSelect<From>(SqlExpression<From> expr)
            {
                if (!expr.OrderByExpression.IsNullOrEmpty() && expr.Rows == null)
                {
                    var modelDef = expr.ModelDef;
                    expr.Select(this.GetQuotedColumnName(modelDef, modelDef.PrimaryKey))
                        .ClearLimits()
                        .OrderBy(""); //Invalid in Sub Selects
    
                    var subSql = expr.ToSelectStatement();
    
                    return subSql;
                }
    
                return base.GetLoadChildrenSubSelect(expr);
            }
    
            public override string SqlCurrency(string fieldOrValue, string currencySymbol) =>
                SqlConcat(new[] { "'" + currencySymbol + "'", $"CONVERT(VARCHAR, CONVERT(MONEY, {fieldOrValue}), 1)" });
    
            public override string SqlBool(bool value) => value ? "1" : "0";
    
            public override string SqlLimit(int? offset = null, int? rows = null) => rows == null && offset == null
                ? ""
                : rows != null
                    ? "OFFSET " + offset.GetValueOrDefault() + " ROWS FETCH NEXT " + rows + " ROWS ONLY"
                    : "OFFSET " + offset.GetValueOrDefault(int.MaxValue) + " ROWS";
    
            public override string SqlCast(object fieldOrValue, string castAs) =>
                castAs == Sql.VARCHAR
                    ? $"CAST({fieldOrValue} AS VARCHAR(MAX))"
                    : $"CAST({fieldOrValue} AS {castAs})";
    
            //public override string SqlRandom => "NEWID()";
    
            //public override void EnableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("EXEC sp_msforeachtable \"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all\"");
            //public override Task EnableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) =>
            //    cmd.ExecNonQueryAsync("EXEC sp_msforeachtable \"ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all\"", null, token);
            //public override void DisableForeignKeysCheck(IDbCommand cmd) => cmd.ExecNonQuery("EXEC sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\"");
            //public override Task DisableForeignKeysCheckAsync(IDbCommand cmd, CancellationToken token = default) =>
            //    cmd.ExecNonQueryAsync("EXEC sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\"", null, token);
    
            protected DbConnection Unwrap(IDbConnection db) => (DbConnection)db.ToDbConnection();
    
            protected DbCommand Unwrap(IDbCommand cmd) => (DbCommand)cmd.ToDbCommand();
    
            protected DbDataReader Unwrap(IDataReader reader) => (DbDataReader)reader;
    
    #if ASYNC
            public override Task OpenAsync(IDbConnection db, CancellationToken token = default)
                => Unwrap(db).OpenAsync(token);
    
            public override Task<IDataReader> ExecuteReaderAsync(IDbCommand cmd, CancellationToken token = default)
                => Unwrap(cmd).ExecuteReaderAsync(token).Then(x => (IDataReader)x);
    
            public override Task<int> ExecuteNonQueryAsync(IDbCommand cmd, CancellationToken token = default)
                => Unwrap(cmd).ExecuteNonQueryAsync(token);
    
            public override Task<object> ExecuteScalarAsync(IDbCommand cmd, CancellationToken token = default)
                => Unwrap(cmd).ExecuteScalarAsync(token);
    
            public override Task<bool> ReadAsync(IDataReader reader, CancellationToken token = default)
                => Unwrap(reader).ReadAsync(token);
    
            public override async Task<List<T>> ReaderEach<T>(IDataReader reader, Func<T> fn, CancellationToken token = default)
            {
                try
                {
                    var to = new List<T>();
                    while (await ReadAsync(reader, token).ConfigureAwait(false))
                    {
                        var row = fn();
                        to.Add(row);
                    }
                    return to;
                }
                finally
                {
                    reader.Dispose();
                }
            }
    
            public override async Task<Return> ReaderEach<Return>(IDataReader reader, Action fn, Return source, CancellationToken token = default)
            {
                try
                {
                    while (await ReadAsync(reader, token).ConfigureAwait(false))
                    {
                        fn();
                    }
                    return source;
                }
                finally
                {
                    reader.Dispose();
                }
            }
    
            public override async Task<T> ReaderRead<T>(IDataReader reader, Func<T> fn, CancellationToken token = default)
            {
                try
                {
                    if (await ReadAsync(reader, token).ConfigureAwait(false))
                        return fn();
    
                    return default(T);
                }
                finally
                {
                    reader.Dispose();
                }
            }
    #endif
    
            //public override void InitConnection(IDbConnection dbConn)
            //{
            //    if (dbConn is OrmLiteConnection ormLiteConn && dbConn.ToDbConnection() is SqlConnection sqlConn)
            //        ormLiteConn.ConnectionId = sqlConn.ClientConnectionId;
    
            //    foreach (var command in ConnectionCommands)
            //    {
            //        using var cmd = dbConn.CreateCommand();
            //        cmd.ExecNonQuery(command);
            //    }
    
            //    OnOpenConnection?.Invoke(dbConn);
            //}
        }
    
    
        public enum BulkInsertMode
        {
            Optimized,
            Csv,
            Sql,
        }
    
        public class BulkInsertConfig
        {
            public int BatchSize { get; set; } = 1000;
            public BulkInsertMode Mode { get; set; } = BulkInsertMode.Csv;
            public ICollection<string>? InsertFields { get; set; } = null;
        }
    
        //public static class OrmLiteConfigExtensions
        //{
        //    private static Dictionary typeModelDefinitionMap = new Dictionary();
        //    internal static bool CheckForIdField(IEnumerable objProperties)
        //    {
        //        // Not using Linq.Where() and manually iterating through objProperties just to avoid dependencies on System.Xml??
        //        foreach (var objProperty in objProperties)
        //        {
        //            if (objProperty.Name != OrmLiteConfig.IdField) continue;
        //            return true;
        //        }
        //        return false;
        //    }
        //    internal static ModelDefinition GetModelDefinition(this Type modelType)
        //    {
        //        if (typeModelDefinitionMap.TryGetValue(modelType, out var modelDef))
        //            return modelDef;
    
        //        if (modelType.IsValueType || modelType == typeof(string))
        //            return null;
    
        //        var modelAliasAttr = modelType.FirstAttribute();
        //        var schemaAttr = modelType.FirstAttribute();
    
        //        var preCreates = modelType.AllAttributes();
        //        var postCreates = modelType.AllAttributes();
        //        var preDrops = modelType.AllAttributes();
        //        var postDrops = modelType.AllAttributes();
    
        //        string JoinSql(List statements)
        //        {
        //            if (statements.Count == 0)
        //                return null;
        //            var sb = StringBuilderCache.Allocate();
        //            foreach (var sql in statements)
        //            {
        //                if (sb.Length > 0)
        //                    sb.AppendLine(";");
        //                sb.Append(sql);
        //            }
        //            var to = StringBuilderCache.ReturnAndFree(sb);
        //            return to;
        //        }
    
        //        modelDef = new ModelDefinition
        //        {
        //            ModelType = modelType,
        //            Name = modelType.Name,
        //            Alias = modelAliasAttr?.Name,
        //            Schema = schemaAttr?.Name,
        //            PreCreateTableSql = JoinSql(preCreates.Map(x => x.Sql)),
        //            PostCreateTableSql = JoinSql(postCreates.Map(x => x.Sql)),
        //            PreDropTableSql = JoinSql(preDrops.Map(x => x.Sql)),
        //            PostDropTableSql = JoinSql(postDrops.Map(x => x.Sql)),
        //        };
    
        //        modelDef.CompositeIndexes.AddRange(
        //            modelType.AllAttributes().ToList());
    
        //        modelDef.UniqueConstraints.AddRange(
        //            modelType.AllAttributes().ToList());
    
        //        var objProperties = modelType.GetProperties(
        //            BindingFlags.Public | BindingFlags.Instance).ToList();
    
        //        var hasPkAttr = objProperties.Any(p => p.HasAttributeCached());
    
        //        var hasIdField = CheckForIdField(objProperties);
    
        //        var i = 0;
        //        var propertyInfoIdx = 0;
        //        foreach (var propertyInfo in objProperties)
        //        {
        //            if (propertyInfo.GetIndexParameters().Length > 0)
        //                continue; //Is Indexer
    
        //            var sequenceAttr = propertyInfo.FirstAttribute();
        //            var computeAttr = propertyInfo.FirstAttribute();
        //            var computedAttr = propertyInfo.FirstAttribute();
        //            var persistedAttr = propertyInfo.FirstAttribute();
        //            var customSelectAttr = propertyInfo.FirstAttribute();
        //            var decimalAttribute = propertyInfo.FirstAttribute();
        //            var belongToAttribute = propertyInfo.FirstAttribute();
        //            var referenceAttr = propertyInfo.FirstAttribute();
        //            var referenceFieldAttr = propertyInfo.FirstAttribute();
    
        //            var isRowVersion = propertyInfo.Name == ModelDefinition.RowVersionName
        //                               && (propertyInfo.PropertyType == typeof(ulong) || propertyInfo.PropertyType == typeof(byte[]));
    
        //            var isNullableType = propertyInfo.PropertyType.IsNullableType();
    
        //            var isNullable = (!propertyInfo.PropertyType.IsValueType
        //                              && !propertyInfo.HasAttributeNamed(nameof(RequiredAttribute)))
        //                             || isNullableType;
    
        //            var propertyType = isNullableType
        //                ? Nullable.GetUnderlyingType(propertyInfo.PropertyType)
        //                : propertyInfo.PropertyType;
    
    
        //            Type treatAsType = null;
    
        //            if (propertyType.IsEnum)
        //            {
        //                var enumKind = Converters.EnumConverter.GetEnumKind(propertyType);
        //                if (enumKind == EnumKind.Int)
        //                    treatAsType = Enum.GetUnderlyingType(propertyType);
        //                else if (enumKind == EnumKind.Char)
        //                    treatAsType = typeof(char);
        //            }
    
        //            var isReference = referenceAttr != null || referenceFieldAttr != null;
        //            var isIgnored = propertyInfo.HasAttributeCached() || isReference || computedAttr != null;
    
        //            var isFirst = !isIgnored && i++ == 0;
    
        //            var isAutoId = propertyInfo.HasAttributeCached();
    
        //            var isPrimaryKey = (!hasPkAttr && (propertyInfo.Name == OrmLiteConfig.IdField || (!hasIdField && isFirst)))
        //                               || propertyInfo.HasAttributeNamed(nameof(PrimaryKeyAttribute))
        //                               || isAutoId;
    
        //            var isAutoIncrement = isPrimaryKey && propertyInfo.HasAttributeCached();
    
        //            if (isAutoIncrement && propertyInfo.PropertyType == typeof(Guid))
        //                throw new NotSupportedException($"[AutoIncrement] is only valid for integer properties for {modelType.Name}.{propertyInfo.Name} Guid property use [AutoId] instead");
    
        //            if (isAutoId && (propertyInfo.PropertyType == typeof(int) || propertyInfo.PropertyType == typeof(long)))
        //                throw new NotSupportedException($"[AutoId] is only valid for Guid properties for {modelType.Name}.{propertyInfo.Name} integer property use [AutoIncrement] instead");
    
        //            var aliasAttr = propertyInfo.FirstAttribute();
    
        //            var indexAttr = propertyInfo.FirstAttribute();
        //            var isIndex = indexAttr != null;
        //            var isUnique = isIndex && indexAttr.Unique;
    
        //            var stringLengthAttr = propertyInfo.CalculateStringLength(decimalAttribute);
    
        //            var defaultValueAttr = propertyInfo.FirstAttribute();
    
        //            var referencesAttr = propertyInfo.FirstAttribute();
        //            var fkAttr = propertyInfo.FirstAttribute();
        //            var customFieldAttr = propertyInfo.FirstAttribute();
        //            var chkConstraintAttr = propertyInfo.FirstAttribute();
    
        //            var order = propertyInfoIdx++;
        //            if (customFieldAttr != null) order = customFieldAttr.Order;
    
        //            var fieldDefinition = new FieldDefinition
        //            {
        //                ModelDef = modelDef,
        //                Name = propertyInfo.Name,
        //                Alias = aliasAttr?.Name,
        //                FieldType = propertyType,
        //                FieldTypeDefaultValue = isNullable ? null : propertyType.GetDefaultValue(),
        //                TreatAsType = treatAsType,
        //                PropertyInfo = propertyInfo,
        //                IsNullable = isNullable,
        //                IsPrimaryKey = isPrimaryKey,
        //                AutoIncrement = isPrimaryKey && isAutoIncrement,
        //                AutoId = isAutoId,
        //                IsIndexed = !isPrimaryKey && isIndex,
        //                IsUniqueIndex = isUnique,
        //                IsClustered = indexAttr?.Clustered == true,
        //                IsNonClustered = indexAttr?.NonClustered == true,
        //                IndexName = indexAttr?.Name,
        //                IsRowVersion = isRowVersion,
        //                IgnoreOnInsert = propertyInfo.HasAttributeCached(),
        //                IgnoreOnUpdate = propertyInfo.HasAttributeCached(),
        //                ReturnOnInsert = propertyInfo.HasAttributeCached(),
        //                FieldLength = stringLengthAttr?.MaximumLength,
        //                DefaultValue = defaultValueAttr?.DefaultValue,
        //                CheckConstraint = chkConstraintAttr?.Constraint,
        //                IsUniqueConstraint = propertyInfo.HasAttributeCached(),
        //                ForeignKey = fkAttr == null
        //                    ? referencesAttr != null ? new ForeignKeyConstraint(referencesAttr.Type) : null
        //                    : new ForeignKeyConstraint(fkAttr.Type, fkAttr.OnDelete, fkAttr.OnUpdate, fkAttr.ForeignKeyName),
        //                IsReference = isReference,
        //                GetValueFn = propertyInfo.CreateGetter(),
        //                SetValueFn = propertyInfo.CreateSetter(),
        //                Sequence = sequenceAttr?.Name,
        //                IsComputed = computeAttr != null || computedAttr != null || customSelectAttr != null,
        //                IsPersisted = persistedAttr != null,
        //                ComputeExpression = computeAttr != null ? computeAttr.Expression : string.Empty,
        //                CustomSelect = customSelectAttr?.Sql,
        //                CustomInsert = propertyInfo.FirstAttribute()?.Sql,
        //                CustomUpdate = propertyInfo.FirstAttribute()?.Sql,
        //                Scale = decimalAttribute?.Scale,
        //                BelongToModelName = belongToAttribute?.BelongToTableType.GetModelDefinition().ModelName,
        //                CustomFieldDefinition = customFieldAttr?.Sql,
        //                IsRefType = propertyType.IsRefType(),
        //                Order = order
        //            };
    
        //            if (referenceFieldAttr != null)
        //            {
        //                fieldDefinition.FieldReference = new FieldReference(fieldDefinition)
        //                {
        //                    RefModel = referenceFieldAttr.Model,
        //                    RefId = referenceFieldAttr.Id,
        //                    RefField = referenceFieldAttr.Field ?? propertyInfo.Name,
        //                };
        //            }
    
        //            if (isIgnored)
        //                modelDef.IgnoredFieldDefinitions.Add(fieldDefinition);
        //            else
        //                modelDef.FieldDefinitions.Add(fieldDefinition);
    
        //            if (isRowVersion)
        //                modelDef.RowVersion = fieldDefinition;
        //        }
    
        //        modelDef.AfterInit();
    
        //        Dictionary snapshot, newCache;
        //        do
        //        {
        //            snapshot = typeModelDefinitionMap;
        //            newCache = new Dictionary(typeModelDefinitionMap) { [modelType] = modelDef };
    
        //        } while (!ReferenceEquals(
        //                     Interlocked.CompareExchange(ref typeModelDefinitionMap, newCache, snapshot), snapshot));
    
        //        LicenseUtils.AssertValidUsage(LicenseFeature.OrmLite, QuotaType.Tables, typeModelDefinitionMap.Count);
    
        //        return modelDef;
        //    }
    
        //}
    
        /// 
        /// Compute attribute.
        /// Use to indicate that a property is a Calculated Field.
        /// Use [Persisted] attribute to persist column
        /// 
        [AttributeUsage(AttributeTargets.Property)]
        public class ComputeAttribute : AttributeBase
        {
            public string Expression { get; set; }
    
            public ComputeAttribute() : this(string.Empty) { }
    
            public ComputeAttribute(string expression)
            {
                Expression = expression;
            }
        }
    
        /// 
        /// Ignore calculated C# Property from being persisted in RDBMS Table
        /// 
        [AttributeUsage(AttributeTargets.Property)]
        public class ComputedAttribute : AttributeBase { }
    
        /// 
        /// Whether to persist calculated column
        /// 
        [AttributeUsage(AttributeTargets.Property)]
        public class PersistedAttribute : AttributeBase { }
        /// 
        /// Populate with a field from a foreign table in AutoQuery and Load* APIs
        /// 
        [AttributeUsage(AttributeTargets.Property)]
        public class ReferenceFieldAttribute : AttributeBase
        {
            /// 
            /// Foreign Key Table name
            /// 
            public Type Model { get; set; }
    
            /// 
            /// The Field name on current Model to use for the Foreign Key Table Lookup 
            /// 
            public string Id { get; set; }
    
            /// 
            /// Specify Field to reference (if different from property name)
            /// 
            public string Field { get; set; }
    
            public ReferenceFieldAttribute() { }
            public ReferenceFieldAttribute(Type model, string id)
            {
                Model = model;
                Id = id;
            }
    
            public ReferenceFieldAttribute(Type model, string id, string field)
            {
                Model = model;
                Id = id;
                Field = field;
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    • 554
    • 555
    • 556
    • 557
    • 558
    • 559
    • 560
    • 561
    • 562
    • 563
    • 564
    • 565
    • 566
    • 567
    • 568
    • 569
    • 570
    • 571
    • 572
    • 573
    • 574
    • 575
    • 576
    • 577
    • 578
    • 579
    • 580
    • 581
    • 582
    • 583
    • 584
    • 585
    • 586
    • 587
    • 588
    • 589
    • 590
    • 591
    • 592
    • 593
    • 594
    • 595
    • 596
    • 597
    • 598
    • 599
    • 600
    • 601
    • 602
    • 603
    • 604
    • 605
    • 606
    • 607
    • 608
    • 609
    • 610
    • 611
    • 612
    • 613
    • 614
    • 615
    • 616
    • 617
    • 618
    • 619
    • 620
    • 621
    • 622
    • 623
    • 624
    • 625
    • 626
    • 627
    • 628
    • 629
    • 630
    • 631
    • 632
    • 633
    • 634
    • 635
    • 636
    • 637
    • 638
    • 639
    • 640
    • 641
    • 642
    • 643
    • 644
    • 645
    • 646
    • 647
    • 648
    • 649
    • 650
    • 651
    • 652
    • 653
    • 654
    • 655
    • 656
    • 657
    • 658
    • 659
    • 660
    • 661
    • 662
    • 663
    • 664
    • 665
    • 666
    • 667
    • 668
    • 669
    • 670
    • 671
    • 672
    • 673
    • 674
    • 675
    • 676
    • 677
    • 678
    • 679
    • 680
    • 681
    • 682
    • 683
    • 684
    • 685
    • 686
    • 687
    • 688
    • 689
    • 690
    • 691
    • 692
    • 693
    • 694
    • 695
    • 696
    • 697
    • 698
    • 699
    • 700
    • 701
    • 702
    • 703
    • 704
    • 705
    • 706
    • 707
    • 708
    • 709
    • 710
    • 711
    • 712
    • 713
    • 714
    • 715
    • 716
    • 717
    • 718
    • 719
    • 720
    • 721
    • 722
    • 723
    • 724
    • 725
    • 726
    • 727
    • 728
    • 729
    • 730
    • 731
    • 732
    • 733
    • 734
    • 735
    • 736
    • 737
    • 738
    • 739
    • 740
    • 741
    • 742
    • 743
    • 744
    • 745
    • 746
    • 747
    • 748
    • 749
    • 750
    • 751
    • 752
    • 753
    • 754
    • 755
    • 756
    • 757
    • 758
    • 759
    • 760
    • 761
    • 762
    • 763
    • 764
    • 765
    • 766
    • 767
    • 768
    • 769
    • 770
    • 771
    • 772
    • 773
    • 774
    • 775
    • 776
    • 777
    • 778
    • 779
    • 780
    • 781
    • 782
    • 783
    • 784
    • 785
    • 786
    • 787
    • 788
    • 789
    • 790
    • 791
    • 792
    • 793
    • 794
    • 795
    • 796
    • 797
    • 798
    • 799
    • 800
    • 801
    • 802
    • 803
    • 804
    • 805
    • 806
    • 807
    • 808
    • 809
    • 810
    • 811
    • 812
    • 813
    • 814
    • 815
    • 816
    • 817
    • 818
    • 819
    • 820
    • 821
    • 822
    • 823
    • 824
    • 825
    • 826
    • 827
    • 828
    • 829
    • 830
    • 831
    • 832
    • 833
    • 834
    • 835
    • 836
    • 837
    • 838
    • 839
    • 840
    • 841
    • 842
    • 843
    • 844
    • 845
    • 846
    • 847
    • 848
    • 849
    • 850
    • 851
    • 852
    • 853
    • 854
    • 855
    • 856
    • 857
    • 858
    • 859
    • 860
    • 861
    • 862
    • 863
    • 864
    • 865
    • 866
    • 867
    • 868
    • 869
    • 870
    • 871
    • 872
    • 873
    • 874
    • 875
    • 876
    • 877
    • 878
    • 879
    • 880
    • 881
    • 882
    • 883
    • 884
    • 885
    • 886
    • 887
    • 888
    • 889
    • 890
    • 891
    • 892
    • 893
    • 894
    • 895
    • 896
    • 897
    • 898
    • 899
    • 900
    • 901
    • 902
    • 903
    • 904
    • 905
    • 906
    • 907
    • 908
    • 909
    • 910
    • 911
    • 912
    • 913
    • 914
    • 915
    • 916
    • 917
    • 918
    • 919
    • 920
    • 921
    • 922
    • 923
    • 924
    • 925
    • 926
    • 927
    • 928
    • 929
    • 930
    • 931
    • 932
    • 933
    • 934
    • 935
    • 936
    • 937
    • 938
    • 939
    • 940
    • 941
    • 942
    • 943
    • 944
    • 945
    • 946
    • 947
    • 948
    • 949
    • 950
    • 951
    • 952
    • 953
    • 954
    • 955
    • 956
    • 957
    • 958
    • 959
    • 960
    • 961
    • 962
    • 963
    • 964
    • 965
    • 966
    • 967
    • 968
    • 969
    • 970
    • 971
    • 972
    • 973
    • 974
    • 975
    • 976
    • 977
    • 978
    • 979
    • 980
    • 981
    • 982
    • 983
    • 984
    • 985
    • 986
    • 987
    • 988
    • 989
    • 990
    • 991
    • 992
    • 993
    • 994
    • 995
    • 996
    • 997
    • 998
    • 999
    • 1000
    • 1001
    • 1002
    • 1003
    • 1004
    • 1005
    • 1006
    • 1007
    • 1008
    • 1009
    • 1010
    • 1011
    • 1012
    • 1013
    • 1014
    • 1015
    • 1016
    • 1017
    • 1018
    • 1019
    • 1020
    • 1021
    • 1022
    • 1023
    • 1024
    • 1025
    • 1026
    • 1027
    • 1028
    • 1029
    • 1030
    • 1031
    • 1032
    • 1033
    • 1034
    • 1035
    • 1036
    • 1037
    • 1038
    • 1039
    • 1040
    • 1041
    • 1042
    • 1043
    • 1044
    • 1045
    • 1046
    • 1047
    • 1048
    • 1049
    • 1050
    • 1051
    • 1052
    • 1053
    • 1054
    • 1055
    • 1056
    • 1057
    • 1058
    • 1059
    • 1060
    • 1061
    • 1062
    • 1063
    • 1064
    • 1065
    • 1066
    • 1067
    • 1068
    • 1069
    • 1070
    • 1071
    • 1072
    • 1073
    • 1074
    • 1075
    • 1076
    • 1077
    • 1078
    • 1079
    • 1080
    • 1081
    • 1082
    • 1083
    • 1084
    • 1085
    • 1086
    • 1087
    • 1088
    • 1089
    • 1090
    • 1091
    • 1092
    • 1093
    • 1094
    • 1095
    • 1096
    • 1097
    • 1098
    • 1099
    • 1100
    • 1101
    • 1102
    • 1103
    • 1104
    • 1105
    • 1106
    • 1107
    • 1108
    • 1109
    • 1110
    • 1111
    • 1112
    • 1113
    • 1114
    • 1115
    • 1116
    • 1117
    • 1118
    • 1119
    • 1120
    • 1121
    • 1122
    • 1123
    • 1124
    • 1125
    • 1126
    • 1127
    • 1128
    • 1129
    • 1130
    • 1131
    • 1132
    • 1133
    • 1134
    • 1135
    • 1136
    • 1137
    • 1138
    • 1139
    • 1140
    • 1141
    • 1142
    • 1143
    • 1144
    • 1145
    • 1146
    • 1147
    • 1148
    • 1149
    • 1150
    • 1151
    • 1152
    • 1153
    • 1154
    • 1155
    • 1156
    • 1157
    • 1158
    • 1159
    • 1160
    • 1161
    • 1162
    • 1163
    • 1164
    • 1165
    • 1166
    • 1167
    • 1168
    • 1169
    • 1170
    • 1171
    • 1172
    • 1173
    • 1174
    • 1175
    • 1176
    • 1177
    • 1178
    • 1179
    • 1180
    • 1181
    • 1182
    • 1183
    • 1184
    • 1185
    • 1186
    • 1187
    • 1188
    • 1189
    • 1190
    • 1191
    • 1192
    • 1193
    • 1194
    • 1195
    • 1196
    • 1197
    • 1198
    • 1199
    • 1200
    • 1201
    • 1202
    • 1203
    • 1204
    • 1205
    • 1206
    • 1207
    • 1208
    • 1209
    • 1210
    • 1211
    • 1212
    • 1213
    • 1214
    • 1215
    • 1216
    • 1217
    • 1218
    • 1219
    • 1220
    • 1221
    • 1222
    • 1223
    • 1224
    • 1225
    • 1226
    • 1227
    • 1228
    • 1229
    • 1230
    • 1231
    • 1232
    • 1233
    • 1234
    • 1235
    • 1236
    • 1237
    • 1238
    • 1239
    • 1240
    • 1241
    • 1242
    • 1243
    • 1244
    • 1245
    • 1246
    • 1247
    • 1248
    • 1249
    • 1250
    • 1251
    • 1252
    • 1253
    • 1254
    • 1255
    • 1256
    • 1257
    • 1258
    • 1259
    • 1260
    • 1261
    • 1262
    • 1263
    • 1264
    • 1265
    • 1266
    • 1267
    • 1268
    • 1269
    • 1270
    • 1271
    • 1272
    • 1273
    • 1274
    • 1275
    • 1276
    • 1277
    • 1278
    • 1279
    • 1280
    • 1281
    • 1282
    • 1283
    • 1284
    • 1285
    • 1286
    • 1287
    • 1288
    • 1289
    • 1290
    • 1291
    • 1292
    • 1293
    • 1294
    • 1295
    • 1296
    • 1297
    • 1298
    • 1299
    • 1300
    • 1301
    • 1302
    • 1303
    • 1304
    • 1305
    • 1306
    • 1307
    • 1308
    • 1309
    • 1310
    • 1311
    • 1312
    • 1313
    • 1314
    • 1315
    • 1316
    • 1317
    • 1318
    • 1319
    • 1320
    • 1321
    • 1322
    • 1323
    • 1324
    • 1325
    • 1326
    • 1327
    • 1328
    • 1329
    • 1330
    • 1331
    • 1332
    • 1333
    • 1334
    • 1335
    • 1336
    • 1337
    • 1338
    • 1339
    • 1340
    • 1341
    • 1342
    • 1343
    • 1344
    • 1345
    • 1346
    • 1347
    • 1348
    • 1349
    • 1350
    • 1351
    • 1352
    • 1353
    • 1354
    • 1355
    • 1356
    • 1357
    • 1358
    • 1359
    • 1360
    • 1361
    • 1362
    • 1363
    • 1364
    • 1365
    • 1366
    • 1367
    • 1368
    • 1369
    • 1370
    • 1371
    • 1372
    • 1373
    • 1374
    • 1375
    • 1376
    • 1377
    • 1378
    • 1379
    • 1380
    • 1381
    • 1382
    • 1383
    • 1384
    • 1385
    • 1386
    • 1387
    • 1388
    • 1389
    • 1390
    • 1391
    • 1392
    • 1393
    • 1394
    • 1395
    • 1396
    • 1397
    • 1398
    • 1399
    • 1400
    • 1401
    • 1402
    • 1403
    • 1404
    • 1405
    • 1406
    • 1407
    • 1408
    • 1409
    • 1410
    • 1411
    • 1412
    • 1413
    • 1414
    • 1415
    • 1416
    • 1417
    • 1418
    • 1419
    • 1420
    • 1421
    • 1422
    • 1423
    • 1424
    • 1425
    • 1426
    • 1427
    • 1428
    • 1429
    • 1430
    • 1431
    • 1432
    • 1433
    • 1434
    • 1435
    • 1436
    • 1437
    • 1438
    • 1439
    • 1440
    • 1441
    • 1442
    • 1443
    • 1444
    • 1445
    • 1446
    • 1447
    • 1448
    • 1449
    • 1450
    • 1451
    • 1452
    • 1453
    • 1454
    • 1455
    • 1456
    • 1457
    • 1458
    • 1459
    • 1460
    • 1461
    • 1462
    • 1463
    • 1464
    • 1465
    • 1466
    • 1467
    • 1468
    • 1469
    • 1470
    • 1471
    • 1472
    • 1473
    • 1474
    • 1475
    • 1476
    • 1477
    • 1478
    • 1479
    • 1480
    • 1481
    • 1482
    • 1483
    • 1484
    • 1485
    • 1486
    • 1487
    • 1488
    • 1489
    • 1490
    • 1491
    • 1492
    • 1493
    • 1494
    • 1495
    • 1496
    • 1497
    • 1498
    • 1499
    • 1500
    • 1501
    • 1502
    • 1503
    • 1504
    • 1505
    • 1506
    • 1507
    • 1508
    • 1509
    • 1510
    • 1511
    • 1512
  • 相关阅读:
    Android Studio实现内容丰富的安卓校园新闻浏览平台
    Transformer Encoder-Decoer 结构回顾
    天空卫士加入工信部重点实验室大数据安全工作组
    【Linux 操作系统】I /O输入与输出
    【算法与数据结构】700、LeetCode二叉搜索树中的搜索
    requests爬虫详解
    MATLAB R2023b安装包下载链接
    单臂路由的配置实验
    HDFS的垃圾回收机制
    【FreeRTOS】软件定时器的使用
  • 原文地址:https://blog.csdn.net/qq_35349982/article/details/133861217