mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
## v0.3.20
- 修复 ToList 选择指定对象时,应附加所有字段查询返回; - 修复 Lazy 延时类与实体关系冲突 bug; - 修复 附加对象读取时,记录为空应该返回null,而不是返回非null(字段默认值)对象;
This commit is contained in:
parent
e99fc1973c
commit
d9de8e986b
27
Examples/dbcontext_01/Properties/launchSettings.json
Normal file
27
Examples/dbcontext_01/Properties/launchSettings.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:53030/",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dbcontext_01": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"applicationUrl": "http://localhost:53031/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -18,8 +20,39 @@ namespace FreeSql {
|
|||||||
public IInsert<TEntity> Insert(IEnumerable<TEntity> source) => _ctx._fsql.Insert<TEntity>(source).WithTransaction(_ctx.GetOrBeginTransaction());
|
public IInsert<TEntity> Insert(IEnumerable<TEntity> source) => _ctx._fsql.Insert<TEntity>(source).WithTransaction(_ctx.GetOrBeginTransaction());
|
||||||
|
|
||||||
public IUpdate<TEntity> Update => _ctx._fsql.Update<TEntity>().WithTransaction(_ctx.GetOrBeginTransaction());
|
public IUpdate<TEntity> Update => _ctx._fsql.Update<TEntity>().WithTransaction(_ctx.GetOrBeginTransaction());
|
||||||
|
|
||||||
public IDelete<TEntity> Delete => _ctx._fsql.Delete<TEntity>().WithTransaction(_ctx.GetOrBeginTransaction());
|
public IDelete<TEntity> Delete => _ctx._fsql.Delete<TEntity>().WithTransaction(_ctx.GetOrBeginTransaction());
|
||||||
|
|
||||||
|
//protected Dictionary<string, TEntity> _vals = new Dictionary<string, TEntity>();
|
||||||
|
//protected tableinfo
|
||||||
|
|
||||||
|
//public void Add(TEntity source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void AddRange(TEntity[] source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void AddRange(IEnumerable<TEntity> source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void Update(TEntity source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void UpdateRange(TEntity[] source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void UpdateRange(IEnumerable<TEntity> source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void Remove(TEntity source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void RemoveRange(TEntity[] source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
//public void RemoveRange(IEnumerable<TEntity> source) {
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class BaseDbSet<TEntity> : DbSet<TEntity> where TEntity : class {
|
internal class BaseDbSet<TEntity> : DbSet<TEntity> where TEntity : class {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Version>0.3.19</Version>
|
<Version>0.3.20</Version>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>YeXiangQin</Authors>
|
<Authors>YeXiangQin</Authors>
|
||||||
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Version>0.3.19</Version>
|
<Version>0.3.20</Version>
|
||||||
<Authors>YeXiangQin</Authors>
|
<Authors>YeXiangQin</Authors>
|
||||||
<Description>FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table.</Description>
|
<Description>FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table.</Description>
|
||||||
<PackageProjectUrl>https://github.com/2881099/FreeSql/wiki/Repository</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/2881099/FreeSql/wiki/Repository</PackageProjectUrl>
|
||||||
|
@ -12,7 +12,7 @@ namespace FreeSql.Tests {
|
|||||||
public class UnitTest1 {
|
public class UnitTest1 {
|
||||||
|
|
||||||
public class Order {
|
public class Order {
|
||||||
[Column(IsPrimary = true)]
|
[Column(IsIdentity = true)]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string OrderTitle { get; set; }
|
public string OrderTitle { get; set; }
|
||||||
public string CustomerName { get; set; }
|
public string CustomerName { get; set; }
|
||||||
@ -20,7 +20,7 @@ namespace FreeSql.Tests {
|
|||||||
public virtual List<OrderDetail> OrderDetails { get; set; }
|
public virtual List<OrderDetail> OrderDetails { get; set; }
|
||||||
}
|
}
|
||||||
public class OrderDetail {
|
public class OrderDetail {
|
||||||
[Column(IsPrimary = true)]
|
[Column(IsIdentity = true)]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
public int OrderId { get; set; }
|
public int OrderId { get; set; }
|
||||||
@ -34,6 +34,10 @@ namespace FreeSql.Tests {
|
|||||||
|
|
||||||
public DbSet<Order> Orders { get; set; }
|
public DbSet<Order> Orders { get; set; }
|
||||||
public DbSet<OrderDetail> OrderDetails { get; set; }
|
public DbSet<OrderDetail> OrderDetails { get; set; }
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder builder) {
|
||||||
|
builder.UseFreeSql(g.mysql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Version>0.3.19</Version>
|
<Version>0.3.20</Version>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>YeXiangQin</Authors>
|
<Authors>YeXiangQin</Authors>
|
||||||
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
|
||||||
|
@ -54,16 +54,19 @@ namespace FreeSql.Internal {
|
|||||||
field.Append(", ").Append(parent.DbField);
|
field.Append(", ").Append(parent.DbField);
|
||||||
if (index >= 0) field.Append(" as").Append(++index);
|
if (index >= 0) field.Append(" as").Append(++index);
|
||||||
return false;
|
return false;
|
||||||
|
case ExpressionType.Parameter:
|
||||||
case ExpressionType.MemberAccess:
|
case ExpressionType.MemberAccess:
|
||||||
if (_common.GetTableByEntity(exp.Type) != null) { //加载表所有字段
|
if (_common.GetTableByEntity(exp.Type) != null) { //加载表所有字段
|
||||||
var map = new List<SelectColumnInfo>();
|
var map = new List<SelectColumnInfo>();
|
||||||
ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString);
|
ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString);
|
||||||
parent.Consturctor = map.First().Table.Table.Type.GetConstructor(new Type[0]);
|
var tb = parent.Table = map.First().Table.Table;
|
||||||
|
parent.Consturctor = tb.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 {
|
var child = new ReadAnonymousTypeInfo {
|
||||||
Property = map.First().Table.Table.Type.GetProperty(map[idx].Column.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
|
Property = tb.Properties.TryGetValue(map[idx].Column.CsName, out var tryprop) ? tryprop : tb.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)}" };
|
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);
|
||||||
@ -82,7 +85,8 @@ namespace FreeSql.Internal {
|
|||||||
for (var a = 0; a < newExp.Members.Count; a++) {
|
for (var a = 0; a < newExp.Members.Count; a++) {
|
||||||
var child = new ReadAnonymousTypeInfo {
|
var child = new ReadAnonymousTypeInfo {
|
||||||
Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
|
Property = newExp.Type.GetProperty(newExp.Members[a].Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
|
||||||
CsName = newExp.Members[a].Name, CsType = newExp.Arguments[a].Type };
|
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);
|
||||||
}
|
}
|
||||||
@ -93,22 +97,36 @@ namespace FreeSql.Internal {
|
|||||||
if (index >= 0) field.Append(" as").Append(++index);
|
if (index >= 0) field.Append(" as").Append(++index);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
internal object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index) {
|
internal object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index, bool notRead) {
|
||||||
if (parent.Childs.Any() == false) return dr.GetValue(++index);
|
if (parent.Childs.Any() == false) {
|
||||||
|
if (notRead) {
|
||||||
|
++index;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return dr.GetValue(++index);
|
||||||
|
}
|
||||||
switch (parent.ConsturctorType) {
|
switch (parent.ConsturctorType) {
|
||||||
case ReadAnonymousTypeInfoConsturctorType.Arguments:
|
case ReadAnonymousTypeInfoConsturctorType.Arguments:
|
||||||
var args = new object[parent.Childs.Count];
|
var args = new object[parent.Childs.Count];
|
||||||
for (var a = 0; a < parent.Childs.Count; a++) {
|
for (var a = 0; a < parent.Childs.Count; a++) {
|
||||||
args[a] = Utils.GetDataReaderValue(parent.Childs[a].CsType, ReadAnonymous(parent.Childs[a], dr, ref index));
|
var objval = ReadAnonymous(parent.Childs[a], dr, ref index, notRead);
|
||||||
|
if (notRead == false)
|
||||||
|
args[a] = Utils.GetDataReaderValue(parent.Childs[a].CsType, objval);
|
||||||
}
|
}
|
||||||
return parent.Consturctor.Invoke(args);
|
return parent.Consturctor.Invoke(args);
|
||||||
case ReadAnonymousTypeInfoConsturctorType.Properties:
|
case ReadAnonymousTypeInfoConsturctorType.Properties:
|
||||||
var ret = parent.Consturctor.Invoke(null);
|
var ret = parent.Consturctor.Invoke(null);
|
||||||
|
var isnull = notRead;
|
||||||
for (var b = 0; b < parent.Childs.Count; b++) {
|
for (var b = 0; b < parent.Childs.Count; b++) {
|
||||||
var prop = parent.Childs[b].Property;
|
var prop = parent.Childs[b].Property;
|
||||||
prop.SetValue(ret, Utils.GetDataReaderValue(prop.PropertyType, ReadAnonymous(parent.Childs[b], dr, ref index)), null);
|
var objval = ReadAnonymous(parent.Childs[b], dr, ref index, notRead);
|
||||||
|
var safeval = Utils.GetDataReaderValue(prop.PropertyType, objval);
|
||||||
|
if (isnull == false && safeval == null && parent.Table.ColumnsByCs.TryGetValue(parent.Childs[b].CsName, out var trycol) && trycol.Attribute.IsPrimary)
|
||||||
|
isnull = true;
|
||||||
|
if (isnull == false)
|
||||||
|
prop.SetValue(ret, safeval, null);
|
||||||
}
|
}
|
||||||
return ret;
|
return isnull ? null : ret;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -445,24 +463,26 @@ namespace FreeSql.Internal {
|
|||||||
var other3Exp = ExpressionLambdaToSqlOther(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
var other3Exp = ExpressionLambdaToSqlOther(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
|
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
|
||||||
throw new Exception($"未实现函数表达式 {exp3} 解析");
|
throw new Exception($"未实现函数表达式 {exp3} 解析");
|
||||||
|
case ExpressionType.Parameter:
|
||||||
case ExpressionType.MemberAccess:
|
case ExpressionType.MemberAccess:
|
||||||
var exp4 = exp as MemberExpression;
|
var exp4 = exp as MemberExpression;
|
||||||
if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) return ExpressionLambdaToSql(exp4.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
if (exp4 != null) {
|
||||||
var extRet = "";
|
if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) return ExpressionLambdaToSql(exp4.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
var memberType = exp4.Expression?.Type ?? exp4.Type;
|
var extRet = "";
|
||||||
switch (memberType.FullName) {
|
var memberType = exp4.Expression?.Type ?? exp4.Type;
|
||||||
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); break;
|
switch (memberType.FullName) {
|
||||||
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); break;
|
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); break;
|
||||||
case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); break;
|
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); break;
|
||||||
|
case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); break;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(extRet) == false) return extRet;
|
||||||
|
var other4Exp = ExpressionLambdaToSqlOther(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||||
|
if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp;
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(extRet) == false) return extRet;
|
|
||||||
var other4Exp = ExpressionLambdaToSqlOther(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
|
||||||
if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp;
|
|
||||||
|
|
||||||
var expStack = new Stack<Expression>();
|
var expStack = new Stack<Expression>();
|
||||||
expStack.Push(exp);
|
expStack.Push(exp);
|
||||||
MethodCallExpression callExp = null;
|
MethodCallExpression callExp = null;
|
||||||
var exp2 = exp4.Expression;
|
var exp2 = exp4?.Expression;
|
||||||
while (true) {
|
while (true) {
|
||||||
switch(exp2?.NodeType) {
|
switch(exp2?.NodeType) {
|
||||||
case ExpressionType.Constant:
|
case ExpressionType.Constant:
|
||||||
@ -508,7 +528,11 @@ namespace FreeSql.Internal {
|
|||||||
}
|
}
|
||||||
Func<TableInfo, string, bool, ParameterExpression, MemberExpression, SelectTableInfo> getOrAddTable = (tbtmp, alias, isa, parmExp, mp) => {
|
Func<TableInfo, string, bool, ParameterExpression, MemberExpression, SelectTableInfo> getOrAddTable = (tbtmp, alias, isa, parmExp, mp) => {
|
||||||
var finds = new SelectTableInfo[0];
|
var finds = new SelectTableInfo[0];
|
||||||
if (isa && parmExp != null)
|
if (_selectColumnMap != null) {
|
||||||
|
finds = _tables.Where(a => a.Table.Type == tbtmp.Type).ToArray();
|
||||||
|
if (finds.Any()) finds = new[] { finds.First() };
|
||||||
|
}
|
||||||
|
if (finds.Length != 1 && isa && parmExp != null)
|
||||||
finds = _tables.Where(a => a.Parameter == parmExp).ToArray();
|
finds = _tables.Where(a => a.Parameter == parmExp).ToArray();
|
||||||
if (finds.Length != 1) {
|
if (finds.Length != 1) {
|
||||||
var navdot = string.IsNullOrEmpty(alias) ? new SelectTableInfo[0] : _tables.Where(a2 => a2.Parameter != null && alias.StartsWith($"{a2.Alias}__")).ToArray();
|
var navdot = string.IsNullOrEmpty(alias) ? new SelectTableInfo[0] : _tables.Where(a2 => a2.Parameter != null && alias.StartsWith($"{a2.Alias}__")).ToArray();
|
||||||
@ -605,6 +629,13 @@ namespace FreeSql.Internal {
|
|||||||
alias2 = find2.Alias;
|
alias2 = find2.Alias;
|
||||||
tb2 = tb2tmp;
|
tb2 = tb2tmp;
|
||||||
}
|
}
|
||||||
|
if (exp2.NodeType == ExpressionType.Parameter && expStack.Any() == false) { //附加选择的参数所有列
|
||||||
|
if (_selectColumnMap != null) {
|
||||||
|
foreach (var tb2c in tb2.Columns.Values)
|
||||||
|
_selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = tb2c });
|
||||||
|
if (tb2.Columns.Any()) return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mp2 == null || expStack.Any()) continue;
|
if (mp2 == null || expStack.Any()) continue;
|
||||||
if (tb2.ColumnsByCs.ContainsKey(mp2.Member.Name) == false) { //如果选的是对象,附加所有列
|
if (tb2.ColumnsByCs.ContainsKey(mp2.Member.Name) == false) { //如果选的是对象,附加所有列
|
||||||
if (_selectColumnMap != null) {
|
if (_selectColumnMap != null) {
|
||||||
|
@ -26,6 +26,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
public DataType DataType { get; }
|
public DataType DataType { get; }
|
||||||
protected ICache _cache { get; set; }
|
protected ICache _cache { get; set; }
|
||||||
protected ILogger _log { get; set; }
|
protected ILogger _log { get; set; }
|
||||||
|
protected CommonUtils _util { get; set; }
|
||||||
protected int slaveUnavailables = 0;
|
protected int slaveUnavailables = 0;
|
||||||
private object slaveLock = new object();
|
private object slaveLock = new object();
|
||||||
private Random slaveRandom = new Random();
|
private Random slaveRandom = new Random();
|
||||||
@ -89,7 +90,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
dic.Add(dr.GetName(a), a);
|
dic.Add(dr.GetName(a), a);
|
||||||
indexes = props.Select(a => dic.TryGetValue(a.Name, out var tryint) ? tryint : -1).ToArray();
|
indexes = props.Select(a => dic.TryGetValue(a.Name, out var tryint) ? tryint : -1).ToArray();
|
||||||
}
|
}
|
||||||
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, indexes, dr, 0).Value);
|
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, indexes, dr, 0, _util).Value);
|
||||||
}, cmdType, cmdText, cmdParms);
|
}, cmdType, cmdText, cmdParms);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
dic.Add(dr.GetName(a), a);
|
dic.Add(dr.GetName(a), a);
|
||||||
indexes = props.Select(a => dic.TryGetValue(a.Name, out var tryint) ? tryint : -1).ToArray();
|
indexes = props.Select(a => dic.TryGetValue(a.Name, out var tryint) ? tryint : -1).ToArray();
|
||||||
}
|
}
|
||||||
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, indexes, dr, 0).Value);
|
ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, indexes, dr, 0, _util).Value);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}, cmdType, cmdText, cmdParms);
|
}, cmdType, cmdText, cmdParms);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -211,7 +212,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
List<TTuple> ret = new List<TTuple>();
|
List<TTuple> ret = new List<TTuple>();
|
||||||
Type type = typeof(TTuple);
|
Type type = typeof(TTuple);
|
||||||
_orm.Ado.ExecuteReader(_transaction, dr => {
|
_orm.Ado.ExecuteReader(_transaction, dr => {
|
||||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
|
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr, 0, _commonUtils);
|
||||||
ret.Add((TTuple)read.Value);
|
ret.Add((TTuple)read.Value);
|
||||||
}, CommandType.Text, sql, _params.ToArray());
|
}, CommandType.Text, sql, _params.ToArray());
|
||||||
return ret;
|
return ret;
|
||||||
@ -225,7 +226,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
List<TTuple> ret = new List<TTuple>();
|
List<TTuple> ret = new List<TTuple>();
|
||||||
Type type = typeof(TTuple);
|
Type type = typeof(TTuple);
|
||||||
await _orm.Ado.ExecuteReaderAsync(_transaction, dr => {
|
await _orm.Ado.ExecuteReaderAsync(_transaction, dr => {
|
||||||
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
|
var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr, 0, _commonUtils);
|
||||||
ret.Add((TTuple)read.Value);
|
ret.Add((TTuple)read.Value);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}, CommandType.Text, sql, _params.ToArray());
|
}, CommandType.Text, sql, _params.ToArray());
|
||||||
@ -280,7 +281,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
Type type = typeof(TReturn);
|
Type type = typeof(TReturn);
|
||||||
_orm.Ado.ExecuteReader(_transaction, dr => {
|
_orm.Ado.ExecuteReader(_transaction, dr => {
|
||||||
var index = -1;
|
var index = -1;
|
||||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
|
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||||
}, CommandType.Text, sql, _params.ToArray());
|
}, CommandType.Text, sql, _params.ToArray());
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
@ -294,7 +295,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
Type type = typeof(TReturn);
|
Type type = typeof(TReturn);
|
||||||
await _orm.Ado.ExecuteReaderAsync(_transaction, dr => {
|
await _orm.Ado.ExecuteReaderAsync(_transaction, dr => {
|
||||||
var index = -1;
|
var index = -1;
|
||||||
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
|
ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index, false));
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}, CommandType.Text, sql, _params.ToArray());
|
}, CommandType.Text, sql, _params.ToArray());
|
||||||
return ret;
|
return ret;
|
||||||
@ -387,15 +388,16 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
Expression.Add(dataIndexExp, Expression.Constant(1))
|
Expression.Add(dataIndexExp, Expression.Constant(1))
|
||||||
);
|
);
|
||||||
else {
|
else {
|
||||||
readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp });
|
readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(readExp, readExpAssign),
|
Expression.Assign(readExp, readExpAssign),
|
||||||
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||||
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
||||||
Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)),
|
Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)),
|
||||||
Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
|
Expression.IfThen(Expression.NotEqual(readExpValue, Expression.Constant(null)),
|
||||||
|
//Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
|
||||||
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
|
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -403,7 +405,7 @@ namespace FreeSql.Internal.CommonProvider {
|
|||||||
blockExp.Clear();
|
blockExp.Clear();
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(dataIndexExp, Expression.Constant(0)),
|
Expression.Assign(dataIndexExp, Expression.Constant(0)),
|
||||||
Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(type), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp })),
|
Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(type), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
|
||||||
Expression.Assign(retExp, Expression.Convert(readExpValue, type))
|
Expression.Assign(retExp, Expression.Convert(readExpValue, type))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ namespace FreeSql.Internal.Model {
|
|||||||
public ConstructorInfo Consturctor { get; set; }
|
public ConstructorInfo Consturctor { get; set; }
|
||||||
public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; }
|
public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; }
|
||||||
public List<ReadAnonymousTypeInfo> Childs = new List<ReadAnonymousTypeInfo>();
|
public List<ReadAnonymousTypeInfo> Childs = new List<ReadAnonymousTypeInfo>();
|
||||||
|
public TableInfo Table { get; set; }
|
||||||
}
|
}
|
||||||
enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties }
|
enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties }
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ namespace FreeSql.Internal {
|
|||||||
internal static void RemoveTableByEntity(Type entity, CommonUtils common) {
|
internal static void RemoveTableByEntity(Type entity, CommonUtils common) {
|
||||||
if (entity.FullName.StartsWith("<>f__AnonymousType")) return;
|
if (entity.FullName.StartsWith("<>f__AnonymousType")) return;
|
||||||
var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
|
var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
|
||||||
tbc.TryRemove(entity, out var trytb);
|
if (tbc.TryRemove(entity, out var trytb) && trytb?.TypeLazy != null) tbc.TryRemove(trytb.TypeLazy, out var trylz);
|
||||||
}
|
}
|
||||||
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;
|
||||||
@ -573,6 +573,7 @@ namespace FreeSql.Internal {
|
|||||||
var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault();
|
var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault();
|
||||||
trytb.TypeLazy = type;
|
trytb.TypeLazy = type;
|
||||||
trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true);
|
trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true);
|
||||||
|
tbc.AddOrUpdate(type, trytb, (oldkey, oldval) => trytb);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -648,7 +649,7 @@ namespace FreeSql.Internal {
|
|||||||
//[typeof(JObject)] = true,
|
//[typeof(JObject)] = true,
|
||||||
//[typeof(JArray)] = true,
|
//[typeof(JArray)] = true,
|
||||||
};
|
};
|
||||||
internal static ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, RowInfo>>();
|
internal static ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary<Type, Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>();
|
||||||
internal class RowInfo {
|
internal class RowInfo {
|
||||||
public object Value { get; set; }
|
public object Value { get; set; }
|
||||||
public int DataIndex { get; set; }
|
public int DataIndex { get; set; }
|
||||||
@ -661,31 +662,32 @@ namespace FreeSql.Internal {
|
|||||||
public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
|
public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
|
||||||
}
|
}
|
||||||
internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue");
|
internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue");
|
||||||
internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type type, int[] indexes, DbDataReader row, int dataIndex = 0) {
|
internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type type, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) {
|
||||||
var func = _dicExecuteArrayRowReadClassOrTuple.GetOrAdd(type, s => {
|
var func = _dicExecuteArrayRowReadClassOrTuple.GetOrAdd(type, s => {
|
||||||
var returnTarget = Expression.Label(typeof(RowInfo));
|
var returnTarget = Expression.Label(typeof(RowInfo));
|
||||||
var typeExp = Expression.Parameter(typeof(Type), "type");
|
var typeExp = Expression.Parameter(typeof(Type), "type");
|
||||||
var indexesExp = Expression.Parameter(typeof(int[]), "indexes");
|
var indexesExp = Expression.Parameter(typeof(int[]), "indexes");
|
||||||
var rowExp = Expression.Parameter(typeof(DbDataReader), "row");
|
var rowExp = Expression.Parameter(typeof(DbDataReader), "row");
|
||||||
var dataIndexExp = Expression.Parameter(typeof(int), "dataIndex");
|
var dataIndexExp = Expression.Parameter(typeof(int), "dataIndex");
|
||||||
|
var commonUtilExp = Expression.Parameter(typeof(CommonUtils), "commonUtil");
|
||||||
|
|
||||||
if (type.IsArray) return Expression.Lambda<Func<Type, int[], DbDataReader, int, RowInfo>>(
|
if (type.IsArray) return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
|
||||||
Expression.New(RowInfo.Constructor,
|
Expression.New(RowInfo.Constructor,
|
||||||
GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)),
|
GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)),
|
||||||
//Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
|
//Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
|
||||||
Expression.Add(dataIndexExp, Expression.Constant(1))
|
Expression.Add(dataIndexExp, Expression.Constant(1))
|
||||||
), new[] { typeExp, indexesExp, rowExp, dataIndexExp }).Compile();
|
), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
|
||||||
|
|
||||||
var typeGeneric = type;
|
var typeGeneric = type;
|
||||||
if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First();
|
if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First();
|
||||||
if (typeGeneric.IsEnum ||
|
if (typeGeneric.IsEnum ||
|
||||||
dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
|
dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
|
||||||
return Expression.Lambda<Func<Type, int[], DbDataReader, int, RowInfo>>(
|
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
|
||||||
Expression.New(RowInfo.Constructor,
|
Expression.New(RowInfo.Constructor,
|
||||||
GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)),
|
GetDataReaderValueBlockExpression(type, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)),
|
||||||
//Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
|
//Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
|
||||||
Expression.Add(dataIndexExp, Expression.Constant(1))
|
Expression.Add(dataIndexExp, Expression.Constant(1))
|
||||||
), new[] { typeExp, indexesExp, rowExp, dataIndexExp }).Compile();
|
), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
|
||||||
|
|
||||||
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`");
|
||||||
@ -714,7 +716,7 @@ namespace FreeSql.Internal {
|
|||||||
Expression.Add(dataIndexExp, Expression.Constant(1))
|
Expression.Add(dataIndexExp, Expression.Constant(1))
|
||||||
);
|
);
|
||||||
else {
|
else {
|
||||||
read2ExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(field.FieldType), indexesExp, rowExp, dataIndexExp });
|
read2ExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(field.FieldType), indexesExp, rowExp, dataIndexExp, commonUtilExp });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block2Exp.AddRange(new Expression[] {
|
block2Exp.AddRange(new Expression[] {
|
||||||
@ -741,11 +743,11 @@ namespace FreeSql.Internal {
|
|||||||
Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)),
|
Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)),
|
||||||
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
||||||
});
|
});
|
||||||
return Expression.Lambda<Func<Type, int[], DbDataReader, int, RowInfo>>(
|
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
|
||||||
Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, indexesExp, rowExp, dataIndexExp }).Compile();
|
Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
|
||||||
}
|
}
|
||||||
var rowLenExp = Expression.ArrayLength(rowExp);
|
var rowLenExp = Expression.ArrayLength(rowExp);
|
||||||
return Expression.Lambda<Func<Type, int[], DbDataReader, int, RowInfo>>(
|
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
|
||||||
Expression.Block(
|
Expression.Block(
|
||||||
Expression.IfThen(
|
Expression.IfThen(
|
||||||
Expression.LessThan(dataIndexExp, rowLenExp),
|
Expression.LessThan(dataIndexExp, rowLenExp),
|
||||||
@ -755,11 +757,11 @@ namespace FreeSql.Internal {
|
|||||||
Expression.Add(dataIndexExp, Expression.Constant(1))))
|
Expression.Add(dataIndexExp, Expression.Constant(1))))
|
||||||
),
|
),
|
||||||
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
||||||
), new[] { typeExp, indexesExp, rowExp, dataIndexExp }).Compile();
|
), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == typeof(object) && indexes != null) {
|
if (type == typeof(object) && indexes != null) {
|
||||||
Func<Type, int[], DbDataReader, int, RowInfo> dynamicFunc = (type2, indexes2, row2, dataindex2) => {
|
Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo> dynamicFunc = (type2, indexes2, row2, dataindex2, commonUtils2) => {
|
||||||
dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
|
dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
|
||||||
var expandodic = (IDictionary<string, object>)expando;
|
var expandodic = (IDictionary<string, object>)expando;
|
||||||
var fc = row2.FieldCount;
|
var fc = row2.FieldCount;
|
||||||
@ -771,6 +773,7 @@ namespace FreeSql.Internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//类注入属性
|
//类注入属性
|
||||||
|
var typetb = GetTableByEntity(type, _commonUtils);
|
||||||
var retExp = Expression.Variable(type, "ret");
|
var retExp = Expression.Variable(type, "ret");
|
||||||
var readExp = Expression.Variable(typeof(RowInfo), "read");
|
var readExp = Expression.Variable(typeof(RowInfo), "read");
|
||||||
var readExpValue = Expression.MakeMemberAccess(readExp, RowInfo.PropertyValue);
|
var readExpValue = Expression.MakeMemberAccess(readExp, RowInfo.PropertyValue);
|
||||||
@ -778,12 +781,18 @@ namespace FreeSql.Internal {
|
|||||||
var readExpValueParms = new List<ParameterExpression>();
|
var readExpValueParms = new List<ParameterExpression>();
|
||||||
var readExpsIndex = Expression.Variable(typeof(int), "readsIndex");
|
var readExpsIndex = Expression.Variable(typeof(int), "readsIndex");
|
||||||
var tryidxExp = Expression.Variable(typeof(int), "tryidx");
|
var tryidxExp = Expression.Variable(typeof(int), "tryidx");
|
||||||
var indexesLengthExp = Expression.Parameter(typeof(int), "indexesLength");
|
var readpknullExp = Expression.Variable(typeof(bool), "isnull2");
|
||||||
|
var readpkvalExp = Expression.Variable(typeof(object), "isnull3val");
|
||||||
|
var indexesLengthExp = Expression.Variable(typeof(int), "indexesLength");
|
||||||
var blockExp = new List<Expression>();
|
var blockExp = new List<Expression>();
|
||||||
var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
|
var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
|
||||||
var ctorParms = ctor.GetParameters();
|
var ctorParms = ctor.GetParameters();
|
||||||
if (ctorParms.Length > 0) {
|
if (ctorParms.Length > 0) {
|
||||||
|
blockExp.AddRange(new Expression[] {
|
||||||
|
Expression.Assign(readpknullExp, Expression.Constant(false))
|
||||||
|
});
|
||||||
foreach (var ctorParm in ctorParms) {
|
foreach (var ctorParm in ctorParms) {
|
||||||
|
var ispkExp = new List<Expression>();
|
||||||
Expression readExpAssign = null; //加速缓存
|
Expression readExpAssign = null; //加速缓存
|
||||||
if (ctorParm.ParameterType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
|
if (ctorParm.ParameterType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
|
||||||
GetDataReaderValueBlockExpression(ctorParm.ParameterType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)),
|
GetDataReaderValueBlockExpression(ctorParm.ParameterType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)),
|
||||||
@ -794,30 +803,64 @@ namespace FreeSql.Internal {
|
|||||||
var proptypeGeneric = ctorParm.ParameterType;
|
var proptypeGeneric = ctorParm.ParameterType;
|
||||||
if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
|
if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
|
||||||
if (proptypeGeneric.IsEnum ||
|
if (proptypeGeneric.IsEnum ||
|
||||||
dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(RowInfo.Constructor,
|
dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) {
|
||||||
GetDataReaderValueBlockExpression(ctorParm.ParameterType, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)),
|
|
||||||
|
//判断主键为空,则整个对象不读取
|
||||||
|
blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)));
|
||||||
|
if (typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) && trycol.Attribute.IsPrimary) {
|
||||||
|
ispkExp.Add(
|
||||||
|
Expression.IfThen(
|
||||||
|
Expression.And(
|
||||||
|
Expression.IsFalse(readpknullExp),
|
||||||
|
Expression.Or(
|
||||||
|
Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)),
|
||||||
|
Expression.Equal(readpkvalExp, Expression.Constant(null))
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expression.Assign(readpknullExp, Expression.Constant(true))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
readExpAssign = Expression.New(RowInfo.Constructor,
|
||||||
|
GetDataReaderValueBlockExpression(ctorParm.ParameterType, readpkvalExp),
|
||||||
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
|
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
|
||||||
Expression.Add(dataIndexExp, Expression.Constant(1))
|
Expression.Add(dataIndexExp, Expression.Constant(1))
|
||||||
);
|
);
|
||||||
else {
|
} else {
|
||||||
readExpAssign = Expression.New(RowInfo.Constructor,
|
readExpAssign = Expression.New(RowInfo.Constructor,
|
||||||
Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(ctorParm.ParameterType), indexesExp, rowExp, dataIndexExp }), RowInfo.PropertyValue),
|
Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(ctorParm.ParameterType), indexesExp, rowExp, dataIndexExp, commonUtilExp }), RowInfo.PropertyValue),
|
||||||
Expression.Add(dataIndexExp, Expression.Constant(1)));
|
Expression.Add(dataIndexExp, Expression.Constant(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var varctorParm = Expression.Variable(ctorParm.ParameterType, $"ctorParm{ctorParm.Name}");
|
var varctorParm = Expression.Variable(ctorParm.ParameterType, $"ctorParm{ctorParm.Name}");
|
||||||
readExpValueParms.Add(varctorParm);
|
readExpValueParms.Add(varctorParm);
|
||||||
|
|
||||||
|
ispkExp.Add(
|
||||||
|
Expression.IfThen(
|
||||||
|
Expression.IsFalse(readpknullExp),
|
||||||
|
Expression.IfThenElse(
|
||||||
|
Expression.Equal(readExpValue, Expression.Constant(null)),
|
||||||
|
Expression.Assign(varctorParm, Expression.Default(ctorParm.ParameterType)),
|
||||||
|
Expression.Assign(varctorParm, Expression.Convert(readExpValue, ctorParm.ParameterType))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(tryidxExp, dataIndexExp),
|
Expression.Assign(tryidxExp, dataIndexExp),
|
||||||
Expression.Assign(readExp, readExpAssign),
|
Expression.Assign(readExp, readExpAssign),
|
||||||
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||||
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
Expression.Assign(dataIndexExp, readExpDataIndex)
|
||||||
Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)),
|
),
|
||||||
Expression.Assign(varctorParm, Expression.Default(ctorParm.ParameterType)),
|
Expression.Block(ispkExp)
|
||||||
Expression.Assign(varctorParm, Expression.Convert(readExpValue, ctorParm.ParameterType)))
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
blockExp.Add(Expression.Assign(retExp, Expression.New(ctor, readExpValueParms)));
|
blockExp.Add(
|
||||||
|
Expression.IfThen(
|
||||||
|
Expression.IsFalse(readpknullExp),
|
||||||
|
Expression.Assign(retExp, Expression.New(ctor, readExpValueParms))
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
Expression.Assign(retExp, Expression.New(ctor)),
|
Expression.Assign(retExp, Expression.New(ctor)),
|
||||||
@ -825,12 +868,14 @@ namespace FreeSql.Internal {
|
|||||||
Expression.IfThen(
|
Expression.IfThen(
|
||||||
Expression.NotEqual(indexesExp, Expression.Constant(null)),
|
Expression.NotEqual(indexesExp, Expression.Constant(null)),
|
||||||
Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp))
|
Expression.Assign(indexesLengthExp, Expression.ArrayLength(indexesExp))
|
||||||
)
|
),
|
||||||
|
Expression.Assign(readpknullExp, Expression.Constant(false))
|
||||||
});
|
});
|
||||||
|
|
||||||
var props = type.GetProperties();//.ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase);
|
var props = type.GetProperties();//.ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase);
|
||||||
var propIndex = 0;
|
var propIndex = 0;
|
||||||
foreach (var prop in props) {
|
foreach (var prop in props) {
|
||||||
|
var ispkExp = new List<Expression>();
|
||||||
var propGetSetMethod = prop.GetSetMethod();
|
var propGetSetMethod = prop.GetSetMethod();
|
||||||
Expression readExpAssign = null; //加速缓存
|
Expression readExpAssign = null; //加速缓存
|
||||||
if (prop.PropertyType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
|
if (prop.PropertyType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
|
||||||
@ -842,17 +887,50 @@ namespace FreeSql.Internal {
|
|||||||
var proptypeGeneric = prop.PropertyType;
|
var proptypeGeneric = prop.PropertyType;
|
||||||
if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
|
if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
|
||||||
if (proptypeGeneric.IsEnum ||
|
if (proptypeGeneric.IsEnum ||
|
||||||
dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(RowInfo.Constructor,
|
dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) {
|
||||||
|
|
||||||
|
//判断主键为空,则整个对象不读取
|
||||||
|
blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)));
|
||||||
|
if (typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) && trycol.Attribute.IsPrimary) {
|
||||||
|
ispkExp.Add(
|
||||||
|
Expression.IfThen(
|
||||||
|
Expression.And(
|
||||||
|
Expression.IsFalse(readpknullExp),
|
||||||
|
Expression.Or(
|
||||||
|
Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)),
|
||||||
|
Expression.Equal(readpkvalExp, Expression.Constant(null))
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expression.Block(
|
||||||
|
Expression.Assign(readpknullExp, Expression.Constant(true)),
|
||||||
|
Expression.Assign(retExp, Expression.Constant(null, type))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
readExpAssign = Expression.New(RowInfo.Constructor,
|
||||||
GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp)),
|
GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp)),
|
||||||
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp) }),
|
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp) }),
|
||||||
Expression.Add(tryidxExp, Expression.Constant(1))
|
Expression.Add(tryidxExp, Expression.Constant(1))
|
||||||
);
|
);
|
||||||
else {
|
} else {
|
||||||
++propIndex;
|
++propIndex;
|
||||||
continue;
|
continue;
|
||||||
//readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), indexesExp, rowExp, tryidxExp });
|
//readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), indexesExp, rowExp, tryidxExp });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ispkExp.Add(
|
||||||
|
Expression.IfThen(
|
||||||
|
Expression.IsFalse(readpknullExp),
|
||||||
|
Expression.IfThenElse(
|
||||||
|
Expression.Equal(readExpValue, Expression.Constant(null)),
|
||||||
|
Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
|
||||||
|
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
blockExp.AddRange(new Expression[] {
|
blockExp.AddRange(new Expression[] {
|
||||||
//以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值
|
//以下注释部分为【严格读取】,会损失一点性能,使用 select * from xxx 与属性映射赋值
|
||||||
Expression.IfThenElse(
|
Expression.IfThenElse(
|
||||||
@ -866,10 +944,7 @@ namespace FreeSql.Internal {
|
|||||||
Expression.Assign(readExp, readExpAssign),
|
Expression.Assign(readExp, readExpAssign),
|
||||||
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
|
||||||
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
Expression.Assign(dataIndexExp, readExpDataIndex)),
|
||||||
Expression.IfThenElse(
|
Expression.Block(ispkExp)
|
||||||
Expression.Equal(readExpValue, Expression.Constant(null)),
|
|
||||||
Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
|
|
||||||
Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@ -880,10 +955,10 @@ namespace FreeSql.Internal {
|
|||||||
Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
|
Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
|
||||||
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
|
||||||
});
|
});
|
||||||
return Expression.Lambda<Func<Type, int[], DbDataReader, int, RowInfo>>(
|
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
|
||||||
Expression.Block(new[] { retExp, readExp, tryidxExp, readExpsIndex, indexesLengthExp }.Concat(readExpValueParms), blockExp), new[] { typeExp, indexesExp, rowExp, dataIndexExp }).Compile();
|
Expression.Block(new[] { retExp, readExp, tryidxExp, readpknullExp, readpkvalExp, readExpsIndex, indexesLengthExp }.Concat(readExpValueParms), blockExp), new[] { typeExp, indexesExp, rowExp, dataIndexExp, commonUtilExp }).Compile();
|
||||||
});
|
});
|
||||||
return func(type, indexes, row, dataIndex);
|
return func(type, indexes, row, dataIndex, _commonUtils);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic);
|
internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic);
|
||||||
|
@ -10,11 +10,10 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace FreeSql.MySql {
|
namespace FreeSql.MySql {
|
||||||
class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||||
CommonUtils _util;
|
|
||||||
|
|
||||||
public MySqlAdo() : base(null, null, DataType.MySql) { }
|
public MySqlAdo() : base(null, null, DataType.MySql) { }
|
||||||
public MySqlAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.MySql) {
|
public MySqlAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.MySql) {
|
||||||
this._util = util;
|
base._util = util;
|
||||||
MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null);
|
MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null);
|
||||||
if (slaveConnectionStrings != null) {
|
if (slaveConnectionStrings != null) {
|
||||||
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
||||||
|
@ -10,11 +10,9 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace FreeSql.Oracle {
|
namespace FreeSql.Oracle {
|
||||||
class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||||
CommonUtils _util;
|
|
||||||
|
|
||||||
public OracleAdo() : base(null, null, DataType.Oracle) { }
|
public OracleAdo() : base(null, null, DataType.Oracle) { }
|
||||||
public OracleAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.Oracle) {
|
public OracleAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.Oracle) {
|
||||||
this._util = util;
|
base._util = util;
|
||||||
MasterPool = new OracleConnectionPool("主库", masterConnectionString, null, null);
|
MasterPool = new OracleConnectionPool("主库", masterConnectionString, null, null);
|
||||||
if (slaveConnectionStrings != null) {
|
if (slaveConnectionStrings != null) {
|
||||||
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
||||||
|
@ -12,11 +12,9 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace FreeSql.PostgreSQL {
|
namespace FreeSql.PostgreSQL {
|
||||||
class PostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
class PostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||||
CommonUtils _util;
|
|
||||||
|
|
||||||
public PostgreSQLAdo() : base(null, null, DataType.PostgreSQL) { }
|
public PostgreSQLAdo() : base(null, null, DataType.PostgreSQL) { }
|
||||||
public PostgreSQLAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.PostgreSQL) {
|
public PostgreSQLAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.PostgreSQL) {
|
||||||
this._util = util;
|
base._util = util;
|
||||||
MasterPool = new PostgreSQLConnectionPool("主库", masterConnectionString, null, null);
|
MasterPool = new PostgreSQLConnectionPool("主库", masterConnectionString, null, null);
|
||||||
if (slaveConnectionStrings != null) {
|
if (slaveConnectionStrings != null) {
|
||||||
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
||||||
|
@ -10,11 +10,9 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace FreeSql.SqlServer {
|
namespace FreeSql.SqlServer {
|
||||||
class SqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
class SqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||||
CommonUtils _util;
|
|
||||||
|
|
||||||
public SqlServerAdo() : base(null, null, DataType.SqlServer) { }
|
public SqlServerAdo() : base(null, null, DataType.SqlServer) { }
|
||||||
public SqlServerAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.SqlServer) {
|
public SqlServerAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.SqlServer) {
|
||||||
this._util = util;
|
base._util = util;
|
||||||
MasterPool = new SqlServerConnectionPool("主库", masterConnectionString, null, null);
|
MasterPool = new SqlServerConnectionPool("主库", masterConnectionString, null, null);
|
||||||
if (slaveConnectionStrings != null) {
|
if (slaveConnectionStrings != null) {
|
||||||
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
||||||
|
@ -10,11 +10,9 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace FreeSql.Sqlite {
|
namespace FreeSql.Sqlite {
|
||||||
class SqliteAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
class SqliteAdo : FreeSql.Internal.CommonProvider.AdoProvider {
|
||||||
CommonUtils _util;
|
|
||||||
|
|
||||||
public SqliteAdo() : base(null, null, DataType.Sqlite) { }
|
public SqliteAdo() : base(null, null, DataType.Sqlite) { }
|
||||||
public SqliteAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.Sqlite) {
|
public SqliteAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log, DataType.Sqlite) {
|
||||||
this._util = util;
|
base._util = util;
|
||||||
MasterPool = new SqliteConnectionPool("主库", masterConnectionString, null, null);
|
MasterPool = new SqliteConnectionPool("主库", masterConnectionString, null, null);
|
||||||
if (slaveConnectionStrings != null) {
|
if (slaveConnectionStrings != null) {
|
||||||
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
foreach (var slaveConnectionString in slaveConnectionStrings) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user