mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
反射+缓存性能优化,接近dapper
This commit is contained in:
parent
57088da71b
commit
ed239835c6
@ -6,6 +6,8 @@ using Xunit;
|
|||||||
using Dapper;
|
using Dapper;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace FreeSql.Tests.PerformanceTest {
|
namespace FreeSql.Tests.PerformanceTest {
|
||||||
public class MySqlAdoTest {
|
public class MySqlAdoTest {
|
||||||
@ -143,6 +145,41 @@ namespace FreeSql.Tests.PerformanceTest {
|
|||||||
sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*");
|
sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToListLimit10() {
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var time = new Stopwatch();
|
||||||
|
|
||||||
|
time.Restart();
|
||||||
|
var dplist1Count = 0;
|
||||||
|
var p1 = Parallel.For(1, 50, b => {
|
||||||
|
List<xxx> dplist1 = new List<xxx>();
|
||||||
|
for (var a = 0; a < 1000; a++) {
|
||||||
|
using (var conn = g.mysql.Ado.MasterPool.Get()) {
|
||||||
|
dplist1.AddRange(Dapper.SqlMapper.Query<xxx>(conn.Value, "select * from song limit 50").ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Interlocked.Exchange(ref dplist1Count, dplist1.Count);
|
||||||
|
});
|
||||||
|
while (p1.IsCompleted == false) ;
|
||||||
|
time.Stop();
|
||||||
|
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1Count}; ORM: Dapper");
|
||||||
|
|
||||||
|
|
||||||
|
time.Restart();
|
||||||
|
var t3Count = 0;
|
||||||
|
var p3 = Parallel.For(1, 50, b => {
|
||||||
|
List<xxx> t3 = new List<xxx>();
|
||||||
|
for (var a = 0; a < 1000; a++) {
|
||||||
|
t3.AddRange(g.mysql.Select<xxx>().Limit(50).ToList());
|
||||||
|
}
|
||||||
|
Interlocked.Exchange(ref t3Count, t3.Count);
|
||||||
|
});
|
||||||
|
while (p3.IsCompleted == false) ;
|
||||||
|
time.Stop();
|
||||||
|
sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3Count}; ORM: FreeSql*");
|
||||||
|
}
|
||||||
|
|
||||||
[Table(Name = "song")]
|
[Table(Name = "song")]
|
||||||
class xxx {
|
class xxx {
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
@ -7,7 +7,7 @@ using System.Text;
|
|||||||
public class g {
|
public class g {
|
||||||
|
|
||||||
public static IFreeSql mysql = new FreeSql.FreeSqlBuilder()
|
public static IFreeSql mysql = new FreeSql.FreeSqlBuilder()
|
||||||
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
|
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=100")
|
||||||
.UseLogger(new LoggerFactory().CreateLogger("FreeSql.MySql"))
|
.UseLogger(new LoggerFactory().CreateLogger("FreeSql.MySql"))
|
||||||
.UseAutoSyncStructure(false)
|
.UseAutoSyncStructure(false)
|
||||||
.Build();
|
.Build();
|
||||||
|
@ -34,6 +34,9 @@ namespace FreeSql.Tests.MySql {
|
|||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ToList() {
|
public void ToList() {
|
||||||
|
var t0 = select.Limit(50).ToList();
|
||||||
|
|
||||||
|
|
||||||
var t1 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
|
var t1 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
|
||||||
var t2 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
|
var t2 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
|
||||||
|
|
||||||
|
@ -58,7 +58,9 @@ namespace FreeSql.Internal {
|
|||||||
parent.Consturctor = map.First().Table.Table.Type.GetConstructor(new Type[0]);
|
parent.Consturctor = map.First().Table.Table.Type.GetConstructor(new Type[0]);
|
||||||
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
|
||||||
for (var idx = 0; idx < map.Count; idx++) {
|
for (var idx = 0; idx < map.Count; idx++) {
|
||||||
var child = new ReadAnonymousTypeInfo { CsName = map[idx].Column.CsName, DbField = $"{map[idx].Table.Alias}.{_common.QuoteSqlName(map[idx].Column.Attribute.Name)}" };
|
var child = new ReadAnonymousTypeInfo {
|
||||||
|
Property = map.First().Table.Table.Type.GetProperty(map[idx].Column.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
|
||||||
|
CsName = map[idx].Column.CsName, DbField = $"{map[idx].Table.Alias}.{_common.QuoteSqlName(map[idx].Column.Attribute.Name)}" };
|
||||||
field.Append(", ").Append(_common.QuoteReadColumn(map[idx].Column.CsType, child.DbField));
|
field.Append(", ").Append(_common.QuoteReadColumn(map[idx].Column.CsType, child.DbField));
|
||||||
if (index >= 0) field.Append(" as").Append(++index);
|
if (index >= 0) field.Append(" as").Append(++index);
|
||||||
parent.Childs.Add(child);
|
parent.Childs.Add(child);
|
||||||
@ -75,7 +77,9 @@ namespace FreeSql.Internal {
|
|||||||
parent.Consturctor = newExp.Type.GetConstructors()[0];
|
parent.Consturctor = newExp.Type.GetConstructors()[0];
|
||||||
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments;
|
parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Arguments;
|
||||||
for (var a = 0; a < newExp.Members.Count; a++) {
|
for (var a = 0; a < newExp.Members.Count; a++) {
|
||||||
var child = new ReadAnonymousTypeInfo { CsName = newExp.Members[a].Name, CsType = newExp.Arguments[a].Type };
|
var child = new ReadAnonymousTypeInfo {
|
||||||
|
Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
|
||||||
|
CsName = newExp.Members[a].Name, CsType = newExp.Arguments[a].Type };
|
||||||
parent.Childs.Add(child);
|
parent.Childs.Add(child);
|
||||||
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString);
|
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString);
|
||||||
}
|
}
|
||||||
@ -98,7 +102,8 @@ namespace FreeSql.Internal {
|
|||||||
case ReadAnonymousTypeInfoConsturctorType.Properties:
|
case ReadAnonymousTypeInfoConsturctorType.Properties:
|
||||||
var ret = parent.Consturctor.Invoke(null);
|
var ret = parent.Consturctor.Invoke(null);
|
||||||
for (var b = 0; b < parent.Childs.Count; b++) {
|
for (var b = 0; b < parent.Childs.Count; b++) {
|
||||||
Utils.FillPropertyValue(ret, parent.Childs[b].CsName, ReadAnonymous(parent.Childs[b], dr, ref index));
|
var prop = parent.Childs[b].Property;
|
||||||
|
prop.SetValue(ret, Utils.GetDataReaderValue(prop.PropertyType, ReadAnonymous(parent.Childs[b], dr, ref index)), null);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using FreeSql.Internal.Model;
|
using FreeSql.Internal.Model;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
@ -220,14 +221,18 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
}
|
}
|
||||||
protected (ReadAnonymousTypeInfo map, string field) GetAllField() {
|
protected (ReadAnonymousTypeInfo map, string field) GetAllField() {
|
||||||
var type = typeof(T1);
|
var type = typeof(T1);
|
||||||
var map = new ReadAnonymousTypeInfo { Consturctor = type.GetConstructor(new Type[0]), ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
|
if (Utils._dicClassConstructor.TryGetValue(type, out var classInfo) == false) {
|
||||||
|
classInfo = new Utils._dicClassConstructorInfo { Constructor = type.GetConstructor(new Type[0]), Properties = type.GetProperties() };
|
||||||
|
Utils._dicClassConstructor.TryAdd(type, classInfo);
|
||||||
|
}
|
||||||
|
var map = new ReadAnonymousTypeInfo { Consturctor = classInfo.Constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
|
||||||
var field = new StringBuilder();
|
var field = new StringBuilder();
|
||||||
var dicfield = new Dictionary<string, bool>();
|
var dicfield = new Dictionary<string, bool>();
|
||||||
var tb = _tables.First();
|
var tb = _tables.First();
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var ps = typeof(T1).GetProperties();
|
var ps = classInfo.Properties;
|
||||||
foreach (var p in ps) {
|
foreach (var p in ps) {
|
||||||
var child = new ReadAnonymousTypeInfo { CsName = p.Name };
|
var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name };
|
||||||
if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
|
if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
|
||||||
if (index > 0) field.Append(", ");
|
if (index > 0) field.Append(", ");
|
||||||
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
|
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
|
||||||
@ -248,7 +253,9 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
++index;
|
++index;
|
||||||
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
|
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
|
||||||
else dicfield.Add(quoteName, true);
|
else dicfield.Add(quoteName, true);
|
||||||
child.Childs.Add(new ReadAnonymousTypeInfo { CsName = col2.CsName });
|
child.Childs.Add(new ReadAnonymousTypeInfo {
|
||||||
|
Property = tb2.Table.Type.GetProperty(col2.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
|
||||||
|
CsName = col2.CsName });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map.Childs.Add(child);
|
map.Childs.Add(child);
|
||||||
|
@ -20,6 +20,7 @@ namespace FreeSql.Internal {
|
|||||||
internal abstract string Mod(string left, string right, Type leftType, Type rightType);
|
internal abstract string Mod(string left, string right, Type leftType, Type rightType);
|
||||||
internal abstract string QuoteWriteParamter(Type type, string paramterName);
|
internal abstract string QuoteWriteParamter(Type type, string paramterName);
|
||||||
internal abstract string QuoteReadColumn(Type type, string columnName);
|
internal abstract string QuoteReadColumn(Type type, string columnName);
|
||||||
|
internal abstract string DbName { get; }
|
||||||
|
|
||||||
internal ICodeFirst CodeFirst { get; set; }
|
internal ICodeFirst CodeFirst { get; set; }
|
||||||
internal TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this);
|
internal TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this);
|
||||||
|
@ -5,6 +5,7 @@ using System.Text;
|
|||||||
|
|
||||||
namespace FreeSql.Internal.Model {
|
namespace FreeSql.Internal.Model {
|
||||||
class ReadAnonymousTypeInfo {
|
class ReadAnonymousTypeInfo {
|
||||||
|
public PropertyInfo Property { get; set; }
|
||||||
public string CsName { get; set; }
|
public string CsName { get; set; }
|
||||||
public Type CsType { get; set; }
|
public Type CsType { get; set; }
|
||||||
public string DbField { get; set; }
|
public string DbField { get; set; }
|
||||||
|
@ -21,7 +21,7 @@ namespace FreeSql.Internal {
|
|||||||
static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>();
|
static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>();
|
||||||
internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
|
internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
|
||||||
if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
|
if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
|
||||||
if (_cacheGetTableByEntity.TryGetValue($"{common.QuoteSqlName("db")}{entity.FullName}", out var trytb)) return trytb; //区分数据库类型缓存
|
if (_cacheGetTableByEntity.TryGetValue($"{common.DbName}-{entity.FullName}", out var trytb)) return trytb; //区分数据库类型缓存
|
||||||
if (common.CodeFirst.GetDbInfo(entity) != null) return null;
|
if (common.CodeFirst.GetDbInfo(entity) != null) return null;
|
||||||
|
|
||||||
var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
|
var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
|
||||||
@ -163,6 +163,16 @@ namespace FreeSql.Internal {
|
|||||||
{ typeof(JObject).FullName, true },
|
{ typeof(JObject).FullName, true },
|
||||||
{ typeof(JArray).FullName, true },
|
{ typeof(JArray).FullName, true },
|
||||||
};
|
};
|
||||||
|
internal static ConcurrentDictionary<Type, _dicClassConstructorInfo> _dicClassConstructor = new ConcurrentDictionary<Type, _dicClassConstructorInfo>();
|
||||||
|
internal static ConcurrentDictionary<Type, _dicTupleConstructorInfo> _dicTupleConstructor = new ConcurrentDictionary<Type, _dicTupleConstructorInfo>();
|
||||||
|
internal class _dicClassConstructorInfo {
|
||||||
|
public ConstructorInfo Constructor { get; set; }
|
||||||
|
public PropertyInfo[] Properties { get; set; }
|
||||||
|
}
|
||||||
|
internal class _dicTupleConstructorInfo {
|
||||||
|
public ConstructorInfo Constructor { get; set; }
|
||||||
|
public Type[] Types { get; set; }
|
||||||
|
}
|
||||||
internal static (object value, int dataIndex) ExecuteArrayRowReadClassOrTuple(Type type, Dictionary<string, int> names, object[] row, int dataIndex = 0) {
|
internal static (object value, int dataIndex) ExecuteArrayRowReadClassOrTuple(Type type, Dictionary<string, int> names, object[] row, int dataIndex = 0) {
|
||||||
if (type.IsArray) return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
|
if (type.IsArray) return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
|
||||||
var typeGeneric = type;
|
var typeGeneric = type;
|
||||||
@ -173,17 +183,18 @@ namespace FreeSql.Internal {
|
|||||||
if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组
|
if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组
|
||||||
bool isTuple = type.Name.StartsWith("ValueTuple`");
|
bool isTuple = type.Name.StartsWith("ValueTuple`");
|
||||||
if (isTuple) {
|
if (isTuple) {
|
||||||
var fs = type.GetFields();
|
if (_dicTupleConstructor.TryGetValue(type, out var tupleInfo) == false) {
|
||||||
var types = new Type[fs.Length];
|
var types = type.GetFields().Select(a => a.FieldType).ToArray();
|
||||||
var parms = new object[fs.Length];
|
tupleInfo = new _dicTupleConstructorInfo { Constructor = type.GetConstructor(types), Types = types };
|
||||||
for (int a = 0; a < fs.Length; a++) {
|
_dicTupleConstructor.AddOrUpdate(type, tupleInfo, (t2, c2) => tupleInfo);
|
||||||
types[a] = fs[a].FieldType;
|
}
|
||||||
var read = ExecuteArrayRowReadClassOrTuple(types[a], names, row, dataIndex);
|
var parms = new object[tupleInfo.Types.Length];
|
||||||
|
for (int a = 0; a < parms.Length; a++) {
|
||||||
|
var read = ExecuteArrayRowReadClassOrTuple(tupleInfo.Types[a], names, row, dataIndex);
|
||||||
if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
|
if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
|
||||||
parms[a] = read.value;
|
parms[a] = read.value;
|
||||||
}
|
}
|
||||||
var constructor = type.GetConstructor(types);
|
return (tupleInfo.Constructor?.Invoke(parms), dataIndex);
|
||||||
return (constructor?.Invoke(parms), dataIndex);
|
|
||||||
}
|
}
|
||||||
return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
|
return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
|
||||||
}
|
}
|
||||||
@ -195,14 +206,18 @@ namespace FreeSql.Internal {
|
|||||||
return (expando, names.Count);
|
return (expando, names.Count);
|
||||||
}
|
}
|
||||||
//类注入属性
|
//类注入属性
|
||||||
var value = type.GetConstructor(new Type[0]).Invoke(new object[0]);
|
if (_dicClassConstructor.TryGetValue(type, out var classInfo)== false) {
|
||||||
var ps = type.GetProperties();
|
classInfo = new _dicClassConstructorInfo { Constructor = type.GetConstructor(new Type[0]), Properties = type.GetProperties() };
|
||||||
foreach(var p in ps) {
|
_dicClassConstructor.TryAdd(type, classInfo);
|
||||||
|
}
|
||||||
|
var value = classInfo.Constructor.Invoke(new object[0]);
|
||||||
|
foreach(var prop in classInfo.Properties) {
|
||||||
var tryidx = dataIndex;
|
var tryidx = dataIndex;
|
||||||
if (names != null && names.TryGetValue(p.Name, out tryidx) == false) continue;
|
if (names != null && names.TryGetValue(prop.Name, out tryidx) == false) continue;
|
||||||
var read = ExecuteArrayRowReadClassOrTuple(p.PropertyType, names, row, tryidx);
|
var read = ExecuteArrayRowReadClassOrTuple(prop.PropertyType, names, row, tryidx);
|
||||||
if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
|
if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
|
||||||
FillPropertyValue(value, p.Name, read.value);
|
prop.SetValue(value, GetDataReaderValue(prop.PropertyType, read.value), null);
|
||||||
|
//FillPropertyValue(value, p.Name, read.value);
|
||||||
//p.SetValue(value, read.value);
|
//p.SetValue(value, read.value);
|
||||||
}
|
}
|
||||||
return (value, dataIndex);
|
return (value, dataIndex);
|
||||||
|
@ -9,6 +9,7 @@ namespace FreeSql.MySql {
|
|||||||
|
|
||||||
class MySqlUtils : CommonUtils {
|
class MySqlUtils : CommonUtils {
|
||||||
IFreeSql _orm;
|
IFreeSql _orm;
|
||||||
|
|
||||||
public MySqlUtils(IFreeSql orm) {
|
public MySqlUtils(IFreeSql orm) {
|
||||||
_orm = orm;
|
_orm = orm;
|
||||||
}
|
}
|
||||||
@ -72,5 +73,6 @@ namespace FreeSql.MySql {
|
|||||||
}
|
}
|
||||||
return columnName;
|
return columnName;
|
||||||
}
|
}
|
||||||
|
internal override string DbName => "MySql";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,5 +48,6 @@ namespace FreeSql.Oracle {
|
|||||||
|
|
||||||
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
||||||
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
||||||
|
internal override string DbName => "Oracle";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,5 +104,6 @@ namespace FreeSql.PostgreSQL {
|
|||||||
|
|
||||||
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
||||||
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
||||||
|
internal override string DbName => "PostgreSQL";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,5 +42,6 @@ namespace FreeSql.SqlServer {
|
|||||||
|
|
||||||
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
||||||
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
||||||
|
internal override string DbName => "SqlServer";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,5 +63,6 @@ namespace FreeSql.Sqlite {
|
|||||||
|
|
||||||
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName;
|
||||||
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
internal override string QuoteReadColumn(Type type, string columnName) => columnName;
|
||||||
|
internal override string DbName => "Sqlite";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user