- 增加 Column.MapType 类型映射,可将 enum 映射为 int/string 等;

This commit is contained in:
28810
2019-04-26 06:30:30 +08:00
parent 205421f7e0
commit 24df5d6107
47 changed files with 4131 additions and 827 deletions

View File

@ -46,6 +46,6 @@ namespace FreeSql.DataAnnotations {
/// <summary>
/// 类型映射,比如:可将 enum 属性映射成 typeof(string)
/// </summary>
public Type Mapping { get; set; }
public Type MapType { get; set; }
}
}

View File

@ -1,4 +1,6 @@
namespace FreeSql.DataAnnotations {
using System;
namespace FreeSql.DataAnnotations {
public class ColumnFluent {
public ColumnFluent(ColumnAttribute column) {
@ -62,5 +64,14 @@
_column.IsVersion = value;
return this;
}
/// <summary>
/// 类型映射,比如:可将 enum 属性映射成 typeof(string)
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public ColumnFluent MapType(Type type) {
_column.MapType = type;
return this;
}
}
}

View File

@ -41,18 +41,30 @@ namespace FreeSql.Extensions.EntityUtil {
Expression.Assign(var3IsNull, Expression.Constant(false))
});
for (var a = 0; a < pks.Length; a++) {
var isguid = pks[a].CsType.NullableTypeOrThis() == typeof(Guid);
var isguid = pks[a].Attribute.MapType.NullableTypeOrThis() == typeof(Guid) || pks[a].CsType.NullableTypeOrThis() == typeof(Guid);
Expression expthen = null;
if (isguid) {
expthen = Expression.Block(
new Expression[]{
Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Call(MethodFreeUtilNewMongodbId)),
a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null,
Expression.Call(var2Sb, MethodStringBuilderAppend,
Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object))
)
}.Where(c => c != null).ToArray()
);
if (pks[a].Attribute.MapType == pks[a].CsType) {
expthen = Expression.Block(
new Expression[]{
Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), Expression.Call(MethodFreeUtilNewMongodbId)),
a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null,
Expression.Call(var2Sb, MethodStringBuilderAppend,
Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object))
)
}.Where(c => c != null).ToArray()
);
} else {
expthen = Expression.Block(
new Expression[]{
Expression.Assign(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pks[a].CsType, Expression.Call(MethodFreeUtilNewMongodbId))),
a > 0 ? Expression.Call(var2Sb, MethodStringBuilderAppend, Expression.Constant(splitString)) : null,
Expression.Call(var2Sb, MethodStringBuilderAppend,
Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pks[a].CsName]), typeof(object))
)
}.Where(c => c != null).ToArray()
);
}
} else if (pks.Length > 1 && pks[a].Attribute.IsIdentity) {
expthen = Expression.Block(
new Expression[]{
@ -405,14 +417,23 @@ namespace FreeSql.Extensions.EntityUtil {
Expression.Assign(var1Parm, Expression.TypeAs(parm1, t))
});
foreach (var pk in _table.Primarys) {
if (pk.CsType == typeof(Guid) || pk.CsType == typeof(Guid?) ||
pk.Attribute.IsIdentity) {
if (pk.Attribute.IsIdentity || pk.Attribute.MapType == pk.CsType && pk.Attribute.MapType.NullableTypeOrThis() == typeof(Guid)) {
exps.Add(
Expression.Assign(
Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]),
Expression.Default(pk.CsType)
)
);
continue;
}
if (pk.Attribute.MapType != pk.CsType && (pk.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) || pk.CsType.NullableTypeOrThis() == typeof(Guid))) {
exps.Add(
Expression.Assign(
Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]),
FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(pk.CsType, Expression.Default(pk.Attribute.MapType))
)
);
continue;
}
}
return Expression.Lambda<Action<object>>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile();

View File

@ -13,18 +13,21 @@ namespace FreeSql.Internal {
internal abstract class CommonExpression {
internal CommonUtils _common;
internal CommonProvider.AdoProvider _ado => _adoPriv ?? (_adoPriv = _common._orm.Ado as CommonProvider.AdoProvider);
CommonProvider.AdoProvider _adoPriv;
internal CommonExpression(CommonUtils common) {
_common = common;
}
static ConcurrentDictionary<Type, PropertyInfo[]> _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary<Type, PropertyInfo[]>();
internal bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
Func<ExpTSC> getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where };
switch (exp.NodeType) {
case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString);
case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString);
case ExpressionType.Negate:
case ExpressionType.NegateChecked:
parent.DbField = $"-({ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, SelectTableInfoType.From, true, false, ExpressionStyle.Where)})";
parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})";
field.Append(", ").Append(parent.DbField);
if (index >= 0) field.Append(" as").Append(++index);
return false;
@ -51,7 +54,7 @@ namespace FreeSql.Internal {
callExp.Arguments[0].Type.FullName == "System.String")
parent.DbField = (callExp.Arguments[0] as ConstantExpression).Value?.ToString() ?? "NULL";
else
parent.DbField = ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, SelectTableInfoType.From, true, false, ExpressionStyle.Where);
parent.DbField = ExpressionLambdaToSql(exp, getTSC());
field.Append(", ").Append(parent.DbField);
if (index >= 0) field.Append(" as").Append(++index);
return false;
@ -67,17 +70,19 @@ namespace FreeSql.Internal {
var child = new ReadAnonymousTypeInfo {
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)}",
CsType = map[idx].Column.CsType
CsType = map[idx].Column.CsType,
MapType = map[idx].Column.Attribute.MapType
};
field.Append(", ").Append(_common.QuoteReadColumn(map[idx].Column.CsType, child.DbField));
field.Append(", ").Append(_common.QuoteReadColumn(child.MapType, child.DbField));
if (index >= 0) field.Append(" as").Append(++index);
parent.Childs.Add(child);
}
} else {
parent.CsType = exp.Type;
parent.DbField = ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, SelectTableInfoType.From, true, false, ExpressionStyle.Where);
parent.DbField = ExpressionLambdaToSql(exp, getTSC());
field.Append(", ").Append(parent.DbField);
if (index >= 0) field.Append(" as").Append(++index);
parent.MapType = SearchColumnByField(_tables, null, parent.DbField)?.Attribute.MapType ?? exp.Type;
return false;
}
return false;
@ -93,7 +98,8 @@ namespace FreeSql.Internal {
var child = new ReadAnonymousTypeInfo {
Property = initExp.Type.GetProperty(initExp.Bindings[a].Member.Name, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance),
CsName = initExp.Bindings[a].Member.Name,
CsType = initAssignExp.Expression.Type
CsType = initAssignExp.Expression.Type,
MapType = initAssignExp.Expression.Type
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString);
@ -107,7 +113,8 @@ namespace FreeSql.Internal {
var child = new ReadAnonymousTypeInfo {
Property = dtoProp,
CsName = dtoProp.Name,
CsType = dtoProp.PropertyType
CsType = dtoProp.PropertyType,
MapType = trydtocol.Attribute.MapType
};
parent.Childs.Add(child);
if (dtTb.Parameter != null)
@ -133,7 +140,8 @@ namespace FreeSql.Internal {
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
CsType = newExp.Arguments[a].Type,
MapType = newExp.Arguments[a].Type
};
parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString);
@ -148,7 +156,8 @@ namespace FreeSql.Internal {
var child = new ReadAnonymousTypeInfo {
Property = dtoProp,
CsName = dtoProp.Name,
CsType = dtoProp.PropertyType
CsType = dtoProp.PropertyType,
MapType = trydtocol.Attribute.MapType
};
parent.Childs.Add(child);
if (dtTb.Parameter != null)
@ -166,7 +175,7 @@ namespace FreeSql.Internal {
}
return true;
}
parent.DbField = $"({ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, SelectTableInfoType.From, true, false, ExpressionStyle.Where)})";
parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})";
field.Append(", ").Append(parent.DbField);
if (index >= 0) field.Append(" as").Append(++index);
return false;
@ -177,7 +186,9 @@ namespace FreeSql.Internal {
++index;
return Utils.GetDataReaderValue(parent.CsType, null);
}
return Utils.GetDataReaderValue(parent.CsType, dr.GetValue(++index));
if (parent.CsType == parent.MapType)
return Utils.GetDataReaderValue(parent.CsType, dr.GetValue(++index));
return Utils.GetDataReaderValue(parent.CsType, Utils.GetDataReaderValue(parent.MapType, dr.GetValue(++index)));
}
switch (parent.ConsturctorType) {
case ReadAnonymousTypeInfoConsturctorType.Arguments:
@ -204,10 +215,25 @@ namespace FreeSql.Internal {
return null;
}
internal string ExpressionConstant(ConstantExpression exp) => _common.FormatSql("{0}", exp?.Value);
internal ColumnInfo SearchColumnByField(List<SelectTableInfo> _tables, TableInfo currentTable, string field) {
if (_tables != null) {
var testCol = _common.TrimQuoteSqlName(field).Split(new[] { '.' }, 2);
if (testCol.Length == 2) {
var testTb = _tables.Where(a => a.Alias == testCol[0]).ToArray();
if (testTb.Length == 1 && testTb[0].Table.Columns.TryGetValue(testCol[1], out var trytstcol))
return trytstcol;
}
}
if (currentTable != null) {
var testCol = _common.TrimQuoteSqlName(field);
if (currentTable.Columns.TryGetValue(testCol, out var trytstcol))
return trytstcol;
}
return null;
}
internal string ExpressionSelectColumn_MemberAccess(List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) {
return ExpressionLambdaToSql(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, false, ExpressionStyle.SelectColumns);
return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns });
}
internal string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List<SelectTableInfo> _tables, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) {
@ -250,9 +276,9 @@ namespace FreeSql.Internal {
{ ExpressionType.Modulo, "%" },
{ ExpressionType.Equal, "=" },
};
internal string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
var sql = ExpressionLambdaToSql(exp, _tables, _selectColumnMap, getSelectGroupingMapString, SelectTableInfoType.From, true, false, ExpressionStyle.Where);
switch(sql) {
internal string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table });
switch (sql) {
case "1":
case "'t'": return "1=1";
case "0":
@ -262,7 +288,7 @@ namespace FreeSql.Internal {
}
internal string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
var sql = ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, SelectTableInfoType.From, true, false, ExpressionStyle.Where);
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
switch (sql) {
case "1":
case "'t'": return "1=1";
@ -273,7 +299,7 @@ namespace FreeSql.Internal {
}
internal void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString) {
var tbidx = _tables.Count;
var filter = ExpressionLambdaToSql(exp, _tables, null, getSelectGroupingMapString, tbtype, true, false, ExpressionStyle.Where);
var filter = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where });
switch (filter) {
case "1":
case "'t'": filter = "1=1"; break;
@ -300,50 +326,80 @@ namespace FreeSql.Internal {
static ConcurrentDictionary<Type, MethodInfo> _dicExpressionLambdaToSqlAsSelectAnyMethodInfo = new ConcurrentDictionary<Type, MethodInfo>();
static ConcurrentDictionary<Type, PropertyInfo> _dicNullableValueProperty = new ConcurrentDictionary<Type, PropertyInfo>();
static ConcurrentDictionary<Type, Expression> _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary<Type, Expression>();
internal string ExpressionLambdaToSql(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) {
var left = ExpressionLambdaToSql(leftExp, tsc);
var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left);
var isLeftMapType = leftMapColumn != null && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type);
ColumnInfo rightMapColumn = null;
var isRightMapType = false;
if (isLeftMapType) tsc.mapType = leftMapColumn.Attribute.MapType;
var right = ExpressionLambdaToSql(rightExp, tsc);
if (right != "NULL" && isLeftMapType) {
var enumType = leftMapColumn.CsType.NullableTypeOrThis();
if (enumType.IsEnum)
right = formatSql(Enum.Parse(enumType, right.Trim('\'')), leftMapColumn.Attribute.MapType);
}
if (leftMapColumn == null) {
rightMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, right);
isRightMapType = rightMapColumn != null && (rightMapColumn.Attribute.MapType != leftExp.Type || rightMapColumn.CsType != leftExp.Type);
if (isRightMapType) {
tsc.mapType = rightMapColumn.Attribute.MapType;
left = ExpressionLambdaToSql(leftExp, tsc);
if (left != "NULL" && isRightMapType) {
var enumType = rightMapColumn.CsType.NullableTypeOrThis();
if (enumType.IsEnum)
left = formatSql(Enum.Parse(enumType, left.Trim('\'')), rightMapColumn.Attribute.MapType);
}
}
}
if (left == "NULL") {
var tmp = right;
right = left;
left = tmp;
}
if (right == "NULL") oper = oper == "=" ? " IS " : " IS NOT ";
if (oper == "+" && (leftExp.Type.FullName == "System.String" || rightExp.Type.FullName == "System.String")) return _common.StringConcat(new[] { left, right }, new[] { leftExp.Type, rightExp.Type });
if (oper == "%") return _common.Mod(left, right, leftExp.Type, rightExp.Type);
tsc.mapType = null;
return $"{left} {oper} {right}";
}
internal string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) {
if (exp == null) return "";
if (isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) {
var args = new AopParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, true, style));
if (tsc.isDisableDiyParse == false && _common._orm.Aop.ParseExpression != null) {
var args = new AopParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(exp, tsc.CloneDisableDiyParse()));
_common._orm.Aop.ParseExpression?.Invoke(this, args);
if (string.IsNullOrEmpty(args.Result) == false) return args.Result;
}
switch (exp.NodeType) {
case ExpressionType.Not: return $"not({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)})";
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case ExpressionType.Not: return $"not({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc)})";
case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc);
case ExpressionType.TypeAs:
case ExpressionType.Convert:
//var othercExp = ExpressionLambdaToSqlOther(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
//var othercExp = ExpressionLambdaToSqlOther(exp, tsc);
//if (string.IsNullOrEmpty(othercExp) == false) return othercExp;
return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
case ExpressionType.Negate:
case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case ExpressionType.Constant: return _common.FormatSql("{0}", (exp as ConstantExpression)?.Value);
case ExpressionType.NegateChecked: return "-" + ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc);
case ExpressionType.Constant: return formatSql((exp as ConstantExpression)?.Value, tsc.mapType);
case ExpressionType.Conditional:
var condExp = exp as ConditionalExpression;
return $"case when {ExpressionLambdaToSql(condExp.Test, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)} then {ExpressionLambdaToSql(condExp.IfTrue, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)} else {ExpressionLambdaToSql(condExp.IfFalse, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)} end";
return $"case when {ExpressionLambdaToSql(condExp.Test, tsc)} then {ExpressionLambdaToSql(condExp.IfTrue, tsc)} else {ExpressionLambdaToSql(condExp.IfFalse, tsc)} end";
case ExpressionType.Call:
var exp3 = exp as MethodCallExpression;
var callType = exp3.Object?.Type ?? exp3.Method.DeclaringType;
switch (callType.FullName) {
case "System.String": return ExpressionLambdaToSqlCallString(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case "System.Math": return ExpressionLambdaToSqlCallMath(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case "System.DateTime": return ExpressionLambdaToSqlCallDateTime(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case "System.TimeSpan": return ExpressionLambdaToSqlCallTimeSpan(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case "System.Convert": return ExpressionLambdaToSqlCallConvert(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
}
if (exp3.Method.Name == "Equals" && exp3.Object != null && exp3.Arguments.Count > 0) {
var tmptryoper = "=";
var tmpleft = ExpressionLambdaToSql(exp3.Object, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var tmpright = ExpressionLambdaToSql(exp3.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
if (tmpleft == "NULL") {
var tmp33 = tmpright;
tmpright = tmpleft;
tmpleft = tmp33;
}
if (tmpright == "NULL") tmptryoper = " IS ";
return $"{tmpleft} {tmptryoper} {tmpright}";
case "System.String": return ExpressionLambdaToSqlCallString(exp3, tsc);
case "System.Math": return ExpressionLambdaToSqlCallMath(exp3, tsc);
case "System.DateTime": return ExpressionLambdaToSqlCallDateTime(exp3, tsc);
case "System.TimeSpan": return ExpressionLambdaToSqlCallTimeSpan(exp3, tsc);
case "System.Convert": return ExpressionLambdaToSqlCallConvert(exp3, tsc);
}
if (exp3.Method.Name == "Equals" && exp3.Object != null && exp3.Arguments.Count > 0)
return ExpressionBinary("=", exp3.Object, exp3.Arguments[0], tsc);
if (callType.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) {
//if (exp3.Type == typeof(string) && exp3.Arguments.Any() && exp3.Arguments[0].NodeType == ExpressionType.Constant) {
// switch (exp3.Method.Name) {
@ -355,10 +411,10 @@ namespace FreeSql.Internal {
//}
switch (exp3.Method.Name) {
case "Count": return "count(1)";
case "Sum": return $"sum({ExpressionLambdaToSql(exp3.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)})";
case "Avg": return $"avg({ExpressionLambdaToSql(exp3.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)})";
case "Max": return $"max({ExpressionLambdaToSql(exp3.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)})";
case "Min": return $"min({ExpressionLambdaToSql(exp3.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)})";
case "Sum": return $"sum({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})";
case "Avg": return $"avg({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})";
case "Max": return $"max({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})";
case "Min": return $"min({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})";
}
}
if (callType.FullName.StartsWith("FreeSql.ISelect`")) { //子表查询
@ -409,7 +465,10 @@ namespace FreeSql.Internal {
var testExecuteExp = asSelectParentExp;
if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联
testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).Properties.First().Value);
asSelectSql = ExpressionLambdaToSql(testExecuteExp, _tables, new List<SelectColumnInfo>(), getSelectGroupingMapString, SelectTableInfoType.LeftJoin, isQuoteName, true, ExpressionStyle.AsSelect);
var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List<SelectColumnInfo>(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin);
tsc2.isDisableDiyParse = true;
tsc2.style = ExpressionStyle.AsSelect;
asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2);
}
}
}
@ -422,8 +481,8 @@ namespace FreeSql.Internal {
if (fsqlType == null) break;
fsqlType.GetField("_limit", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(fsql, 1);
fsqltables = fsqlType.GetField("_tables", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(fsql) as List<SelectTableInfo>;
//fsqltables[0].Alias = $"{_tables[0].Alias}_{fsqltables[0].Alias}";
fsqltables.AddRange(_tables.Select(a => new SelectTableInfo {
//fsqltables[0].Alias = $"{tsc._tables[0].Alias}_{fsqltables[0].Alias}";
fsqltables.AddRange(tsc._tables.Select(a => new SelectTableInfo {
Alias = a.Alias,
On = "1=1",
Table = a.Table,
@ -482,7 +541,7 @@ namespace FreeSql.Internal {
typeof(FreeSqlGlobalExtensions).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(mfil => mfil.Name == "AsSelect" && mfil.GetParameters().Length == 1).FirstOrDefault()?.MakeGenericMethod(refMiddleEntityType3),
Expression.Constant(Activator.CreateInstance(typeof(List<>).MakeGenericType(refMiddleEntityType3)))
));
var manyMainParam = _tables[0].Parameter;
var manyMainParam = tsc._tables[0].Parameter;
var manySubSelectWhereParam = Expression.Parameter(parm123Ref.RefMiddleEntityType, $"M{fsqlWhereParam.Name}_M{asSelectParentExp.ToString().Replace(".", "__")}");//, $"{fsqlWhereParam.Name}__");
Expression manySubSelectWhereExp = null;
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) {
@ -528,7 +587,7 @@ namespace FreeSql.Internal {
manySubSelectExpBoy = Expression.Call(manySubSelectExpBoy, manySubSelectAny);
asSelectBefores.Clear();
return ExpressionLambdaToSql(manySubSelectExpBoy, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
return ExpressionLambdaToSql(manySubSelectExpBoy, tsc);
}
for (var mn = 0; mn < parm123Ref.Columns.Count; mn++) {
var col1 = parm123Ref.RefColumns[mn];
@ -559,23 +618,23 @@ namespace FreeSql.Internal {
// }
//}
var other3Exp = ExpressionLambdaToSqlOther(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var other3Exp = ExpressionLambdaToSqlOther(exp3, tsc);
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
throw new Exception($"未实现函数表达式 {exp3} 解析");
case ExpressionType.Parameter:
case ExpressionType.MemberAccess:
var exp4 = exp as MemberExpression;
if (exp4 != null) {
if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) return ExpressionLambdaToSql(exp4.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
if (exp4.Expression != null && exp4.Expression.Type.IsArray == false && exp4.Expression.Type.IsNullableType()) return ExpressionLambdaToSql(exp4.Expression, tsc);
var extRet = "";
var memberType = exp4.Expression?.Type ?? exp4.Type;
switch (memberType.FullName) {
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); break;
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); break;
case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); break;
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, tsc); break;
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, tsc); break;
case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, tsc); break;
}
if (string.IsNullOrEmpty(extRet) == false) return extRet;
var other4Exp = ExpressionLambdaToSqlOther(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var other4Exp = ExpressionLambdaToSqlOther(exp4, tsc);
if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp;
}
var expStack = new Stack<Expression>();
@ -613,67 +672,67 @@ namespace FreeSql.Internal {
}
break;
}
if (expStack.First().NodeType != ExpressionType.Parameter) return _common.FormatSql("{0}", Expression.Lambda(exp).Compile().DynamicInvoke());
if (callExp != null) return ExpressionLambdaToSql(callExp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
if (getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) {
if (getSelectGroupingMapString != null) {
var expText = getSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray());
if (expStack.First().NodeType != ExpressionType.Parameter) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType);
if (callExp != null) return ExpressionLambdaToSql(callExp, tsc);
if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) {
if (tsc.getSelectGroupingMapString != null) {
var expText = tsc.getSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray());
if (string.IsNullOrEmpty(expText) == false) return expText;
}
}
if (_tables == null) {
if (tsc._tables == null) {
var pp = expStack.Pop() as ParameterExpression;
var memberExp = expStack.Pop() as MemberExpression;
var tb = _common.GetTableByEntity(pp.Type);
if (tb.ColumnsByCs.ContainsKey(memberExp.Member.Name) == false) throw new ArgumentException($"{tb.DbName} 找不到列 {memberExp.Member.Name}");
if (_selectColumnMap != null) {
_selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] });
if (tsc._selectColumnMap != null) {
tsc._selectColumnMap.Add(new SelectColumnInfo { Table = null, Column = tb.ColumnsByCs[memberExp.Member.Name] });
}
var name = tb.ColumnsByCs[memberExp.Member.Name].Attribute.Name;
if (isQuoteName) name = _common.QuoteSqlName(name);
if (tsc.isQuoteName) name = _common.QuoteSqlName(name);
return name;
}
Func<TableInfo, string, bool, ParameterExpression, MemberExpression, SelectTableInfo> getOrAddTable = (tbtmp, alias, isa, parmExp, mp) => {
var finds = new SelectTableInfo[0];
if (style == ExpressionStyle.SelectColumns) {
finds = _tables.Where(a => a.Table.Type == tbtmp.Type).ToArray();
if (tsc.style == ExpressionStyle.SelectColumns) {
finds = tsc._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 = tsc._tables.Where(a => a.Parameter == parmExp).ToArray();
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] : tsc._tables.Where(a2 => a2.Parameter != null && alias.StartsWith($"{a2.Alias}__")).ToArray();
if (navdot.Length > 0) {
var isthis = navdot[0] == _tables[0];
finds = _tables.Where(a2 => (isa && a2.Parameter != null || !isa && a2.Parameter == null) &&
var isthis = navdot[0] == tsc._tables[0];
finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || !isa && a2.Parameter == null) &&
a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") &&
(isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray();
if (finds.Length == 0)
finds = _tables.Where(a2 =>
finds = tsc._tables.Where(a2 =>
a2.Table.Type == tbtmp.Type && a2.Alias == alias && a2.Alias.StartsWith($"{navdot[0].Alias}__") &&
(isthis && a2.Type != SelectTableInfoType.Parent || !isthis && a2.Type == SelectTableInfoType.Parent)).ToArray();
} else {
finds = _tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) &&
finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) &&
a2.Table.Type == tbtmp.Type && a2.Alias == alias).ToArray();
if (finds.Length != 1) {
finds = _tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) &&
finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) &&
a2.Table.Type == tbtmp.Type).ToArray();
if (finds.Length != 1) {
finds = _tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) &&
finds = tsc._tables.Where(a2 => (isa && a2.Parameter != null || isa && a2.Parameter == null) &&
a2.Table.Type == tbtmp.Type).ToArray();
if (finds.Length != 1)
finds = _tables.Where(a2 => a2.Table.Type == tbtmp.Type).ToArray();
finds = tsc._tables.Where(a2 => a2.Table.Type == tbtmp.Type).ToArray();
}
}
}
//finds = _tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && (isthis && a2.Type != SelectTableInfoType.Parent || !isthis)).ToArray(); //外部表,内部表一起查
//finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && (isthis && a2.Type != SelectTableInfoType.Parent || !isthis)).ToArray(); //外部表,内部表一起查
//if (finds.Length > 1) {
// finds = _tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type == SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); //查询外部表
// finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type == SelectTableInfoType.Parent && a2.Alias == alias).ToArray(); //查询外部表
// if (finds.Any() == false) {
// finds = _tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent).ToArray(); //查询内部表
// finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent).ToArray(); //查询内部表
// if (finds.Length > 1)
// finds = _tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent && a2.Alias == alias).ToArray();
// finds = tsc._tables.Where((a2, c2) => (isa || a2.Parameter == null) && a2.Table.CsName == tbtmp.CsName && a2.Type != SelectTableInfoType.Parent && a2.Alias == alias).ToArray();
// }
//}
}
@ -681,11 +740,11 @@ namespace FreeSql.Internal {
if (find != null && isa && parmExp != null && find.Parameter != parmExp)
find.Parameter = parmExp;
if (find == null) {
_tables.Add(find = new SelectTableInfo { Table = tbtmp, Alias = alias, On = null, Type = mp == null ? tbtype : SelectTableInfoType.LeftJoin, Parameter = isa ? parmExp : null });
tsc._tables.Add(find = new SelectTableInfo { Table = tbtmp, Alias = alias, On = null, Type = mp == null ? tsc.tbtype : SelectTableInfoType.LeftJoin, Parameter = isa ? parmExp : null });
if (mp?.Expression != null) { //导航条件OneToOne、ManyToOne
var firstTb = _tables.First().Table;
var firstTb = tsc._tables.First().Table;
var parentTb = _common.GetTableByEntity(mp.Expression.Type);
var parentTbRef = parentTb.GetTableRef(mp.Member.Name, style == ExpressionStyle.AsSelect);
var parentTbRef = parentTb.GetTableRef(mp.Member.Name, tsc.style == ExpressionStyle.AsSelect);
if (parentTbRef != null) {
Expression navCondExp = null;
for (var mn = 0; mn < parentTbRef.Columns.Count; mn++) {
@ -704,9 +763,9 @@ namespace FreeSql.Internal {
if (find.Type == SelectTableInfoType.InnerJoin ||
find.Type == SelectTableInfoType.LeftJoin ||
find.Type == SelectTableInfoType.RightJoin)
find.On = ExpressionLambdaToSql(navCondExp, _tables, null, null, find.Type, isQuoteName, isDisableDiyParse, style);
find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type));
else
find.NavigateCondition = ExpressionLambdaToSql(navCondExp, _tables, null, null, find.Type, isQuoteName, isDisableDiyParse, style);
find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type));
}
}
}
@ -740,29 +799,29 @@ namespace FreeSql.Internal {
tb2 = tb2tmp;
}
if (exp2.NodeType == ExpressionType.Parameter && expStack.Any() == false) { //附加选择的参数所有列
if (_selectColumnMap != null) {
if (tsc._selectColumnMap != null) {
foreach (var tb2c in tb2.Columns.Values)
_selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = tb2c });
tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = tb2c });
if (tb2.Columns.Any()) return "";
}
}
if (mp2 == null || expStack.Any()) continue;
if (tb2.ColumnsByCs.ContainsKey(mp2.Member.Name) == false) { //如果选的是对象,附加所有列
if (_selectColumnMap != null) {
if (tsc._selectColumnMap != null) {
var tb3 = _common.GetTableByEntity(mp2.Type);
if (tb3 != null) {
var find3 = getOrAddTable(tb2tmp, alias2 /*$"{alias2}__{mp2.Member.Name}"*/, exp2.NodeType == ExpressionType.Parameter, parmExp2, mp2);
foreach (var tb3c in tb3.Columns.Values)
_selectColumnMap.Add(new SelectColumnInfo { Table = find3, Column = tb3c });
tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find3, Column = tb3c });
if (tb3.Columns.Any()) return "";
}
}
throw new ArgumentException($"{tb2.DbName} 找不到列 {mp2.Member.Name}");
}
var col2 = tb2.ColumnsByCs[mp2.Member.Name];
if (_selectColumnMap != null && find2 != null) {
_selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 });
if (tsc._selectColumnMap != null && find2 != null) {
tsc._selectColumnMap.Add(new SelectColumnInfo { Table = find2, Column = col2 });
return "";
}
name2 = tb2.ColumnsByCs[mp2.Member.Name].Attribute.Name;
@ -770,63 +829,78 @@ namespace FreeSql.Internal {
case ExpressionType.Call:break;
}
}
if (isQuoteName) name2 = _common.QuoteSqlName(name2);
if (tsc.isQuoteName) name2 = _common.QuoteSqlName(name2);
return $"{alias2}.{name2}";
}
var expBinary = exp as BinaryExpression;
if (expBinary == null) {
var other99Exp = ExpressionLambdaToSqlOther(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var other99Exp = ExpressionLambdaToSqlOther(exp, tsc);
if (string.IsNullOrEmpty(other99Exp) == false) return other99Exp;
return "";
}
switch (expBinary.NodeType) {
case ExpressionType.Coalesce:
return _common.IsNull(ExpressionLambdaToSql(expBinary.Left, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style), ExpressionLambdaToSql(expBinary.Right, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style));
return _common.IsNull(ExpressionLambdaToSql(expBinary.Left, tsc), ExpressionLambdaToSql(expBinary.Right, tsc));
case ExpressionType.OrElse:
return $"({ExpressionLambdaToSql(expBinary.Left, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)} OR {ExpressionLambdaToSql(expBinary.Right, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style)})";
return $"({ExpressionLambdaToSql(expBinary.Left, tsc)} OR {ExpressionLambdaToSql(expBinary.Right, tsc)})";
}
if (dicExpressionOperator.TryGetValue(expBinary.NodeType, out var tryoper) == false) return "";
var left = ExpressionLambdaToSql(expBinary.Left, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var right = ExpressionLambdaToSql(expBinary.Right, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
if (left == "NULL") {
var tmp = right;
right = left;
left = tmp;
}
if (right == "NULL") tryoper = tryoper == "=" ? " IS " : " IS NOT ";
if (tryoper == "+" && (expBinary.Left.Type.FullName == "System.String" || expBinary.Right.Type.FullName == "System.String")) return _common.StringConcat(new[] { left, right }, new[] { expBinary.Left.Type, expBinary.Right.Type });
if (tryoper == "%") return _common.Mod(left, right, expBinary.Left.Type, expBinary.Right.Type);
if (_common._orm.Ado.DataType == DataType.MySql) {
//处理c#变态enum convert a.EnumType1 == Xxx.Xxx被转成了 Convert(a.EnumType1, Int32) == 1
if (expBinary.Left.NodeType == ExpressionType.Convert && expBinary.Right.NodeType == ExpressionType.Constant) {
if (long.TryParse(right, out var tryenumLong)) {
var enumType = (expBinary.Left as UnaryExpression)?.Operand.Type;
if (enumType?.IsEnum == true)
right = _common.FormatSql("{0}", Enum.Parse(enumType, right));
}
} else if (expBinary.Left.NodeType == ExpressionType.Constant && expBinary.Right.NodeType == ExpressionType.Convert) {
if (long.TryParse(left, out var tryenumLong)) {
var enumType = (expBinary.Right as UnaryExpression)?.Operand.Type;
if (enumType?.IsEnum == true)
left = _common.FormatSql("{0}", Enum.Parse(enumType, left));
}
}
}
return $"{left} {tryoper} {right}";
return ExpressionBinary(tryoper, expBinary.Left, expBinary.Right, tsc);
}
internal abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style);
internal abstract string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc);
internal abstract string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc);
internal enum ExpressionStyle {
Where, AsSelect, SelectColumns
}
internal class ExpTSC {
public List<SelectTableInfo> _tables { get; set; }
public List<SelectColumnInfo> _selectColumnMap { get; set; }
public Func<Expression[], string> getSelectGroupingMapString { get; set; }
public SelectTableInfoType tbtype { get; set; }
public bool isQuoteName { get; set; }
public bool isDisableDiyParse { get; set; }
public ExpressionStyle style { get; set; }
public Type mapType { get; set; }
public TableInfo currentTable { get; set; }
public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List<SelectColumnInfo> v1, Func<Expression[], string> v2, SelectTableInfoType v3 ) {
return new ExpTSC {
_tables = this._tables,
_selectColumnMap = v1,
getSelectGroupingMapString = v2,
tbtype = v3,
isQuoteName = this.isQuoteName,
isDisableDiyParse = this.isDisableDiyParse,
style = this.style,
currentTable = this.currentTable
};
}
public ExpTSC CloneDisableDiyParse() {
return new ExpTSC {
_tables = this._tables,
_selectColumnMap = this._selectColumnMap,
getSelectGroupingMapString = this.getSelectGroupingMapString,
tbtype = this.tbtype,
isQuoteName = this.isQuoteName,
isDisableDiyParse = false,
style = this.style,
currentTable = this.currentTable
};
}
}
internal string formatSql(object obj, Type mapType) {
return string.Concat(_ado.AddslashesProcessParam(obj, mapType));
}
}
}

View File

@ -1,9 +1,9 @@
using System.Text.RegularExpressions;
using System;
using System.Text.RegularExpressions;
namespace FreeSql.Internal.CommonProvider {
partial class AdoProvider {
public abstract object AddslashesProcessParam(object param);
public abstract object AddslashesProcessParam(object param, Type mapType);
public string Addslashes(string filter, params object[] parms) {
if (filter == null || parms == null) return string.Empty;
if (parms.Length == 0) return filter;
@ -11,7 +11,7 @@ namespace FreeSql.Internal.CommonProvider {
for (int a = 0; a < parms.Length; a++) {
if (parms[a] == null)
filter = Regex.Replace(filter, @"\s*(=|IN)\s*\{" + a + @"\}", " IS {" + a + "}", RegexOptions.IgnoreCase);
nparms[a] = AddslashesProcessParam(parms[a]);
nparms[a] = AddslashesProcessParam(parms[a], null);
}
try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; }
}

View File

@ -66,7 +66,7 @@ namespace FreeSql.Internal.CommonProvider {
public abstract List<T1> ExecuteDeleted();
public abstract Task<List<T1>> ExecuteDeletedAsync();
public IDelete<T1> Where(Expression<Func<T1, bool>> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, exp?.Body, null));
public IDelete<T1> Where(Expression<Func<T1, bool>> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null));
public IDelete<T1> Where(string sql, object parms = null) {
if (string.IsNullOrEmpty(sql)) return this;
var args = new AopWhereEventArgs(sql, parms);

View File

@ -387,17 +387,14 @@ namespace FreeSql.Internal.CommonProvider {
foreach (var col in _table.Columns.Values)
if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) {
if (colidx2 > 0) sb.Append(", ");
object val = null;
if (_table.Properties.TryGetValue(col.CsName, out var tryp)) {
val = tryp.GetValue(d);
if (col.Attribute.IsPrimary && (col.CsType == typeof(Guid) || col.CsType == typeof(Guid?))
&& (val == null || (Guid)val == Guid.Empty)) tryp.SetValue(d, val = FreeUtil.NewMongodbId());
}
object val = col.GetMapValue(d);
if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty))
col.SetMapValue(d, val = FreeUtil.NewMongodbId());
if (_noneParameter)
sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.CsType, val));
sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val));
else {
sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}")));
_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.CsType, val);
sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}")));
_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val);
}
++colidx2;
}

View File

@ -453,7 +453,7 @@ namespace FreeSql.Internal.CommonProvider {
if (tbiindex > 0 && colidx == 0) field.Append("\r\n");
}
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
field.Append(_commonUtils.QuoteReadColumn(col.CsType, $"{tbi.Alias}.{quoteName}"));
field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tbi.Alias}.{quoteName}"));
++index;
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
else dicfield.Add(quoteName, true);
@ -505,7 +505,7 @@ namespace FreeSql.Internal.CommonProvider {
if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) { //普通字段
if (index > 0) field.Append(", ");
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
field.Append(_commonUtils.QuoteReadColumn(col.CsType, $"{tb.Alias}.{quoteName}"));
field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}"));
++index;
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
else dicfield.Add(quoteName, true);
@ -525,7 +525,7 @@ namespace FreeSql.Internal.CommonProvider {
foreach (var col2 in tb2.Table.Columns.Values) {
if (index > 0) field.Append(", ");
var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name);
field.Append(_commonUtils.QuoteReadColumn(col2.CsType, $"{tb2.Alias}.{quoteName}"));
field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}"));
++index;
++otherindex;
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
@ -607,7 +607,7 @@ namespace FreeSql.Internal.CommonProvider {
if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
if (index > 0) field.Append(", ");
var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
field.Append(_commonUtils.QuoteReadColumn(col.CsType, $"{tb.Alias}.{quoteName}"));
field.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"{tb.Alias}.{quoteName}"));
++index;
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
else dicfield.Add(quoteName, true);
@ -620,7 +620,7 @@ namespace FreeSql.Internal.CommonProvider {
foreach (var col2 in tb2.Table.Columns.Values) {
if (index > 0) field.Append(", ");
var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name);
field.Append(_commonUtils.QuoteReadColumn(col2.CsType, $"{tb2.Alias}.{quoteName}"));
field.Append(_commonUtils.QuoteReadColumn(col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}"));
++index;
if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
else dicfield.Add(quoteName, true);

View File

@ -24,7 +24,7 @@ namespace FreeSql.Internal.CommonProvider {
string getSelectGroupingMapString(Expression[] members) {
if (members.Any() == false) return _map.DbField;
var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name;
switch(parentName) {
switch (parentName) {
case "Key":
var read = _map;
for (var a = 0; a < members.Length; a++) {
@ -53,7 +53,7 @@ namespace FreeSql.Internal.CommonProvider {
var parmExp = Expression.Parameter(tb.Table.Type, tb.Alias);
Expression retExp = parmExp;
for (var a = foridx; a < members.Length; a++) {
switch(members[a].NodeType) {
switch (members[a].NodeType) {
case ExpressionType.Call:
retExp = Expression.Call(retExp, (members[a] as MethodCallExpression).Method);
break;
@ -64,7 +64,7 @@ namespace FreeSql.Internal.CommonProvider {
return null;
}
}
return _comonExp.ExpressionLambdaToSql(retExp, _tables, null, null, SelectTableInfoType.From, true, true, CommonExpression.ExpressionStyle.Where);
return _comonExp.ExpressionLambdaToSql(retExp, new CommonExpression.ExpTSC { _tables = _tables, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = true, style = CommonExpression.ExpressionStyle.Where });
}
return null;
}

View File

@ -301,10 +301,10 @@ namespace FreeSql.Internal.CommonProvider {
var col = cols.First();
_set.Append(", ").Append(_commonUtils.QuoteSqlName(col.Column.Attribute.Name)).Append(" = ");
if (_noneParameter) {
_set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Column.CsType, value));
_set.Append(_commonUtils.GetNoneParamaterSqlValue(_params, col.Column.Attribute.MapType, value));
} else {
_set.Append(_commonUtils.QuoteWriteParamter(col.Column.CsType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}"));
_commonUtils.AppendParamter(_params, null, col.Column.CsType, value);
_set.Append(_commonUtils.QuoteWriteParamter(col.Column.Attribute.MapType, $"{_commonUtils.QuoteParamterName("p_")}{_params.Count}"));
_commonUtils.AppendParamter(_params, null, col.Column.Attribute.MapType, value);
}
//foreach (var t in _source) Utils.FillPropertyValue(t, tryf.CsName, value);
return this;
@ -313,11 +313,11 @@ namespace FreeSql.Internal.CommonProvider {
if (binaryExpression?.Body is BinaryExpression == false &&
binaryExpression?.Body.NodeType != ExpressionType.Call) return this;
var cols = new List<SelectColumnInfo>();
var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, cols, binaryExpression, null);
var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, binaryExpression, null);
if (cols.Any() == false) return this;
foreach (var col in cols) {
if (col.Column.Attribute.IsNullable == true && col.Column.CsType.IsNullableType()) {
var replval = _orm.CodeFirst.GetDbInfo(col.Column.CsType.GenericTypeArguments.FirstOrDefault())?.defaultValue;
if (col.Column.Attribute.IsNullable == true && col.Column.Attribute.MapType.IsNullableType()) {
var replval = _orm.CodeFirst.GetDbInfo(col.Column.Attribute.MapType.GenericTypeArguments.FirstOrDefault())?.defaultValue;
if (replval == null) continue;
var replname = _commonUtils.QuoteSqlName(col.Column.Attribute.Name);
expt = expt.Replace(replname, _commonUtils.IsNull(replname, _commonUtils.FormatSql("{0}", replval)));
@ -333,7 +333,7 @@ namespace FreeSql.Internal.CommonProvider {
return this;
}
public IUpdate<T1> Where(Expression<Func<T1, bool>> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, expression?.Body, null));
public IUpdate<T1> Where(Expression<Func<T1, bool>> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null));
public IUpdate<T1> Where(string sql, object parms = null) {
if (string.IsNullOrEmpty(sql)) return this;
var args = new AopWhereEventArgs(sql, parms);
@ -361,8 +361,7 @@ namespace FreeSql.Internal.CommonProvider {
var sb = new StringBuilder();
sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ");
var value = _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(_source.First()) : DBNull.Value;
sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.CsType, value)));
sb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, col.GetMapValue(_source.First()))));
return sb.ToString();
@ -382,8 +381,8 @@ namespace FreeSql.Internal.CommonProvider {
cwsb.Append(" \r\nWHEN ");
ToSqlWhen(cwsb, _table.Primarys, d);
cwsb.Append(" THEN ");
var value = _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(d) : DBNull.Value;
cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.CsType, value)));
var value = col.GetMapValue(d);
cwsb.Append(thenValue(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value)));
if (isnull == false) isnull = value == null || value == DBNull.Value;
}
cwsb.Append(" END");
@ -427,12 +426,12 @@ namespace FreeSql.Internal.CommonProvider {
if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.CsName) == false) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ");
var value = _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(_source.First()) : null;
var value = col.GetMapValue(_source.First());
if (_noneParameter) {
sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.CsType, value));
sb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value));
} else {
sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
_commonUtils.AppendParamter(_paramsSource, null, col.CsType, value);
sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
_commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value);
}
++colidx;
}
@ -460,12 +459,12 @@ namespace FreeSql.Internal.CommonProvider {
cwsb.Append(" \r\nWHEN ");
ToSqlWhen(cwsb, _table.Primarys, d);
cwsb.Append(" THEN ");
var value = _table.Properties.TryGetValue(col.CsName, out var tryp) ? tryp.GetValue(d) : DBNull.Value;
var value = col.GetMapValue(d);
if (_noneParameter) {
cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.CsType, value));
cwsb.Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, col.Attribute.MapType, value));
} else {
cwsb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
_commonUtils.AppendParamter(_paramsSource, null, col.CsType, value);
cwsb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}")));
_commonUtils.AppendParamter(_paramsSource, null, col.Attribute.MapType, value);
}
if (isnull == false) isnull = value == null || value == DBNull.Value;
}

View File

@ -19,6 +19,7 @@ namespace FreeSql.Internal {
internal abstract DbParameter[] GetDbParamtersByObject(string sql, object obj);
internal abstract string FormatSql(string sql, params object[] args);
internal abstract string QuoteSqlName(string name);
internal abstract string TrimQuoteSqlName(string name);
internal abstract string QuoteParamterName(string name);
internal abstract string IsNull(string sql, object value);
internal abstract string StringConcat(string[] objs, Type[] types);
@ -100,6 +101,7 @@ namespace FreeSql.Internal {
if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable;
if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore;
if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion;
if (trycol.MapType != null) attr.MapType = trycol.MapType;
if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue;
}
var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false);
@ -114,34 +116,38 @@ namespace FreeSql.Internal {
if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable;
if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore;
if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion;
if (tryattr.MapType != null) attr.MapType = tryattr.MapType;
if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue;
}
if (!string.IsNullOrEmpty(attr.Name)) return attr;
if (!string.IsNullOrEmpty(attr.OldName)) return attr;
if (!string.IsNullOrEmpty(attr.DbType)) return attr;
if (attr._IsPrimary != null) return attr;
if (attr._IsIdentity != null) return attr;
if (attr._IsNullable != null) return attr;
if (attr._IsIgnore != null) return attr;
if (attr._IsVersion != null) return attr;
if (attr.DbDefautValue != null) return attr;
return null;
ColumnAttribute ret = null;
if (!string.IsNullOrEmpty(attr.Name)) ret = attr;
if (!string.IsNullOrEmpty(attr.OldName)) ret = attr;
if (!string.IsNullOrEmpty(attr.DbType)) ret = attr;
if (attr._IsPrimary != null) ret = attr;
if (attr._IsIdentity != null) ret = attr;
if (attr._IsNullable != null) ret = attr;
if (attr._IsIgnore != null) ret = attr;
if (attr._IsVersion != null) ret = attr;
if (attr.MapType != null) ret = attr;
if (attr.DbDefautValue != null) ret = attr;
if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType;
return ret;
}
internal string WhereObject(TableInfo table, string aliasAndDot, object dywhere) {
if (dywhere == null) return "";
var type = dywhere.GetType();
var primarys = table.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
if (primarys.Length == 1 && (type == primarys.First().CsType || type.IsNumberType() && primarys.First().CsType.IsNumberType())) {
return $"{aliasAndDot}{this.QuoteSqlName(primarys.First().Attribute.Name)} = {this.FormatSql("{0}", dywhere)}";
var primarys = table.Primarys;
var pk1 = primarys.FirstOrDefault();
if (primarys.Length == 1 && (type == pk1.CsType || type.IsNumberType() && pk1.CsType.IsNumberType())) {
return $"{aliasAndDot}{this.QuoteSqlName(pk1.Attribute.Name)} = {this.FormatSql("{0}", Utils.GetDataReaderValue(pk1.Attribute.MapType, dywhere))}";
} else if (primarys.Length > 0 && (type == table.Type || type.BaseType == table.Type)) {
var sb = new StringBuilder();
var pkidx = 0;
foreach (var pk in primarys) {
var prop = type.GetProperty(pk.CsName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
if (pkidx > 0) sb.Append(" AND ");
sb.Append(aliasAndDot).Append(this.QuoteSqlName(pk.Attribute.Name));
sb.Append(this.FormatSql(" = {0}", prop.GetValue(dywhere)));
sb.Append(this.FormatSql(" = {0}", pk.GetMapValue(dywhere)));
++pkidx;
}
return sb.ToString();
@ -165,7 +171,7 @@ namespace FreeSql.Internal {
if (table.Columns.TryGetValue(p.Name, out var trycol) == false) continue;
if (psidx > 0) sb.Append(" AND ");
sb.Append(aliasAndDot).Append(this.QuoteSqlName(trycol.Attribute.Name));
sb.Append(this.FormatSql(" = {0}", p.GetValue(dywhere)));
sb.Append(this.FormatSql(" = {0}", Utils.GetDataReaderValue(trycol.Attribute.MapType, p.GetValue(dywhere))));
++psidx;
}
if (psidx == 0) return "";
@ -178,14 +184,14 @@ namespace FreeSql.Internal {
if (table.Primarys.Any() == false) return null;
var its = items.Where(a => a != null).ToArray();
var pk1 = table.Primarys.FirstOrDefault();
if (table.Primarys.Length == 1) {
var sbin = new StringBuilder();
sbin.Append(aliasAndDot).Append(this.QuoteSqlName(table.Primarys.First().Attribute.Name));
var indt = its.Select(a => /*this.FormatSql("{0}", _orm.GetEntityKeyValues(a))*/
table.Properties.TryGetValue(table.Primarys.First().CsName, out var trycol) ? this.FormatSql("{0}", trycol.GetValue(a)) : null).Where(a => a != null).ToArray();
sbin.Append(aliasAndDot).Append(this.QuoteSqlName(pk1.Attribute.Name));
var indt = its.Select(a => pk1.GetMapValue(a)).Where(a => a != null).ToArray();
if (indt.Any() == false) return null;
if (indt.Length == 1) sbin.Append(" = ").Append(indt.First());
else sbin.Append(" IN (").Append(string.Join(",", indt)).Append(")");
if (indt.Length == 1) sbin.Append(" = ").Append(this.FormatSql("{0}", indt.First()));
else sbin.Append(" IN (").Append(string.Join(",", indt.Select(a => this.FormatSql("{0}", a)))).Append(")");
return sbin.ToString();
}
var dicpk = its.Length > 5 ? new Dictionary<string, bool>() : null;
@ -193,10 +199,8 @@ namespace FreeSql.Internal {
var iidx = 0;
foreach (var item in its) {
var filter = "";
for (var a = 0; a < table.Primarys.Length; a++) {
if (table.Properties.TryGetValue(table.Primarys[a].CsName, out var trycol) == false) continue;
filter += $" AND {aliasAndDot}{this.QuoteSqlName(table.Primarys[a].Attribute.Name)} = {this.FormatSql("{0}", trycol.GetValue(item))}";
}
foreach (var pk in table.Primarys)
filter += $" AND {aliasAndDot}{this.QuoteSqlName(pk.Attribute.Name)} = {this.FormatSql("{0}", pk.GetMapValue(item))}";
if (string.IsNullOrEmpty(filter)) continue;
if (sb != null) {
sb.Append(" OR (");

View File

@ -1,5 +1,8 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace FreeSql.Internal.Model {
public class ColumnInfo {
@ -7,5 +10,64 @@ namespace FreeSql.Internal.Model {
public string CsName { get; set; }
public Type CsType { get; set; }
public ColumnAttribute Attribute { get; set; }
static ConcurrentDictionary<ColumnInfo, Func<object, object>> _dicGetMapValue = new ConcurrentDictionary<ColumnInfo, Func<object, object>>();
public object GetMapValue(object obj) {
var func = _dicGetMapValue.GetOrAdd(this, col => {
var paramExp = Expression.Parameter(typeof(object));
var returnTarget = Expression.Label(typeof(object));
if (Attribute.MapType == CsType)
return Expression.Lambda<Func<object, object>>(
Expression.Block(
Expression.Return(returnTarget, Expression.Convert(
Expression.MakeMemberAccess(
Expression.TypeAs(paramExp, col.Table.Type),
Table.Properties[col.CsName]
), typeof(object))),
Expression.Label(returnTarget, Expression.Default(typeof(object)))
), new[] { paramExp }).Compile();
var retExp = Expression.Variable(typeof(object), "ret");
var blockExp = new List<Expression>();
blockExp.AddRange(new Expression[] {
Expression.Assign(retExp, Utils.GetDataReaderValueBlockExpression(Attribute.MapType,
Expression.MakeMemberAccess(
Expression.TypeAs(paramExp, col.Table.Type),
Table.Properties[col.CsName]
)
)),
Expression.Return(returnTarget, retExp),
Expression.Label(returnTarget, Expression.Default(typeof(object)))
});
return Expression.Lambda<Func<object, object>>(Expression.Block(new[] { retExp }, blockExp), new[] { paramExp }).Compile();
});
return func(obj);
}
static ConcurrentDictionary<ColumnInfo, Action<object, object>> _dicSetMapValue = new ConcurrentDictionary<ColumnInfo, Action<object, object>>();
public void SetMapValue(object obj, object val) {
var func = _dicSetMapValue.GetOrAdd(this, col => {
var objExp = Expression.Parameter(typeof(object), "obj");
var valExp = Expression.Parameter(typeof(object), "val");
if (Attribute.MapType == CsType)
return Expression.Lambda<Action<object, object>>(
Expression.Assign(Expression.MakeMemberAccess(
Expression.TypeAs(objExp, col.Table.Type),
Table.Properties[col.CsName]
), Expression.Convert(
valExp,
Attribute.MapType)), objExp, valExp).Compile();
return Expression.Lambda<Action<object, object>>(
Expression.Assign(Expression.MakeMemberAccess(
Expression.TypeAs(objExp, col.Table.Type),
Table.Properties[col.CsName]
), Expression.Convert(
Utils.GetDataReaderValueBlockExpression(Attribute.MapType, valExp),
Attribute.MapType)), objExp, valExp).Compile();
});
func(obj, val);
}
}
}

View File

@ -8,6 +8,7 @@ namespace FreeSql.Internal.Model {
public PropertyInfo Property { get; set; }
public string CsName { get; set; }
public Type CsType { get; set; }
public Type MapType { get; set; }
public string DbField { get; set; }
public ConstructorInfo Consturctor { get; set; }
public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; }

View File

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
@ -22,7 +23,11 @@ namespace FreeSql.Internal {
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) {
if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
if (entity.FullName.StartsWith("<>f__AnonymousType") ||
entity.IsValueType ||
entity.IsNullableType() ||
entity.NullableTypeOrThis() == typeof(BigInteger)
) return null;
var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
if (tbc.TryGetValue(entity, out var trytb)) return trytb;
if (common.CodeFirst.GetDbInfo(entity) != null) return null;
@ -49,9 +54,9 @@ namespace FreeSql.Internal {
var propsNavObjs = new List<PropertyInfo>();
foreach (var p in trytb.Properties.Values) {
var setMethod = trytb.Type.GetMethod($"set_{p.Name}");
var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
//if (tp == null) continue;
var colattr = common.GetEntityColumnAttribute(entity, p);
var tp = common.CodeFirst.GetDbInfo(colattr?.MapType ?? p.PropertyType);
//if (tp == null) continue;
if (tp == null && colattr == null) {
if (common.CodeFirst.IsLazyLoading) {
var getIsVirtual = trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual;
@ -69,8 +74,10 @@ namespace FreeSql.Internal {
IsIdentity = false,
IsNullable = tp.Value.isnullable ?? true,
IsPrimary = false,
IsIgnore = false
IsIgnore = false,
MapType = p.PropertyType
};
if (colattr._IsNullable == null) colattr._IsNullable = tp.Value.isnullable;
if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)";
colattr.DbType = colattr.DbType.ToUpper();
@ -92,10 +99,11 @@ namespace FreeSql.Internal {
return tmpLt;
});
colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
if (colattr.DbDefautValue != null && p.PropertyType != colattr.MapType) colattr.DbDefautValue = Utils.GetDataReaderValue(colattr.MapType, colattr.DbDefautValue);
if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
if (colattr.IsNullable == false && colattr.DbDefautValue == null)
colattr.DbDefautValue = Activator.CreateInstance(p.PropertyType.IsNullableType() ? p.PropertyType.GenericTypeArguments.FirstOrDefault() : p.PropertyType);
if (colattr.IsIdentity == true && p.PropertyType.IsNumberType() == false)
colattr.DbDefautValue = Activator.CreateInstance(colattr.MapType.IsNullableType() ? colattr.MapType.GenericTypeArguments.FirstOrDefault() : colattr.MapType);
if (colattr.IsIdentity == true && colattr.MapType.IsNumberType() == false)
colattr.IsIdentity = false;
if (setMethod == null) colattr.IsIgnore = true;
@ -114,7 +122,7 @@ namespace FreeSql.Internal {
}
trytb.VersionColumn = trytb.Columns.Values.Where(a => a.Attribute.IsVersion == true).LastOrDefault();
if (trytb.VersionColumn != null) {
if (trytb.VersionColumn.CsType.IsNullableType() || trytb.VersionColumn.CsType.IsNumberType() == false)
if (trytb.VersionColumn.Attribute.MapType.IsNullableType() || trytb.VersionColumn.Attribute.MapType.IsNumberType() == false)
throw new Exception($"属性{trytb.VersionColumn.CsName} 被标注为行锁(乐观锁)(IsVersion),但其必须为数字类型,并且不可为 Nullable");
}
trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
@ -145,14 +153,14 @@ namespace FreeSql.Internal {
var finddbtbs = common.dbTables.Where(a => string.Compare(a.Name, trytb.CsName, true) == 0 || string.Compare(a.Name, trytb.DbName, true) == 0);
foreach (var dbtb in finddbtbs) {
foreach (var dbident in dbtb.Identitys) {
if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.CsType == dbident.CsType ||
trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.CsType == dbident.CsType) {
if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.Attribute.MapType == dbident.CsType ||
trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.Attribute.MapType == dbident.CsType) {
trycol.Attribute.IsIdentity = true;
}
}
foreach (var dbpk in dbtb.Primarys) {
if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.CsType == dbpk.CsType ||
trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.CsType == dbpk.CsType) {
if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.Attribute.MapType == dbpk.CsType ||
trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.Attribute.MapType == dbpk.CsType) {
trycol.Attribute.IsPrimary = true;
}
}
@ -682,8 +690,8 @@ namespace FreeSql.Internal {
public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
}
internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue");
internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type type, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) {
var func = _dicExecuteArrayRowReadClassOrTuple.GetOrAdd(type, s => {
internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) {
var func = _dicExecuteArrayRowReadClassOrTuple.GetOrAdd(typeOrg, type => {
var returnTarget = Expression.Label(typeof(RowInfo));
var typeExp = Expression.Parameter(typeof(Type), "type");
var indexesExp = Expression.Parameter(typeof(int[]), "indexes");
@ -813,24 +821,25 @@ namespace FreeSql.Internal {
});
foreach (var ctorParm in ctorParms) {
if (typetb.ColumnsByCsIgnore.ContainsKey(ctorParm.Name)) continue;
var readType = typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) ? trycol.Attribute.MapType : ctorParm.ParameterType;
var ispkExp = new List<Expression>();
Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp));
Expression readExpAssign = null; //加速缓存
if (ctorParm.ParameterType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
GetDataReaderValueBlockExpression(ctorParm.ParameterType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), readpkvalExp }),
if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
GetDataReaderValueBlockExpression(readType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }),
Expression.Add(dataIndexExp, Expression.Constant(1))
);
else {
var proptypeGeneric = ctorParm.ParameterType;
var proptypeGeneric = readType;
if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
if (proptypeGeneric.IsEnum ||
dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) {
//判断主键为空,则整个对象不读取
//blockExp.Add(Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)));
if (typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) && trycol.Attribute.IsPrimary == true) {
if (trycol?.Attribute.IsPrimary == true) {
ispkExp.Add(
Expression.IfThen(
Expression.AndAlso(
@ -846,19 +855,22 @@ namespace FreeSql.Internal {
}
readExpAssign = Expression.New(RowInfo.Constructor,
GetDataReaderValueBlockExpression(ctorParm.ParameterType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), readpkvalExp }),
GetDataReaderValueBlockExpression(readType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }),
Expression.Add(dataIndexExp, Expression.Constant(1))
);
} else {
readExpAssign = Expression.New(RowInfo.Constructor,
Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(ctorParm.ParameterType), indexesExp, rowExp, dataIndexExp, commonUtilExp }), RowInfo.PropertyValue),
Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(readType), indexesExp, rowExp, dataIndexExp, commonUtilExp }), RowInfo.PropertyValue),
Expression.Add(dataIndexExp, Expression.Constant(1)));
}
}
var varctorParm = Expression.Variable(ctorParm.ParameterType, $"ctorParm{ctorParm.Name}");
readExpValueParms.Add(varctorParm);
if (trycol != null && trycol.Attribute.MapType != ctorParm.ParameterType)
ispkExp.Add(Expression.Assign(readExpValue, GetDataReaderValueBlockExpression(ctorParm.ParameterType, readExpValue)));
ispkExp.Add(
Expression.IfThen(
Expression.IsFalse(readpknullExp),
@ -869,6 +881,7 @@ namespace FreeSql.Internal {
)
)
);
blockExp.AddRange(new Expression[] {
Expression.Assign(tryidxExp, dataIndexExp),
readVal,
@ -900,25 +913,26 @@ namespace FreeSql.Internal {
var propIndex = 0;
foreach (var prop in props) {
if (typetb.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue;
var readType = typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) ? trycol.Attribute.MapType : prop.PropertyType;
var ispkExp = new List<Expression>();
var propGetSetMethod = prop.GetSetMethod();
Expression readVal = Expression.Assign(readpkvalExp, Expression.Call(rowExp, MethodDataReaderGetValue, tryidxExp));
Expression readExpAssign = null; //加速缓存
if (prop.PropertyType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
GetDataReaderValueBlockExpression(prop.PropertyType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), readpkvalExp }),
if (readType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
GetDataReaderValueBlockExpression(readType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }),
Expression.Add(tryidxExp, Expression.Constant(1))
);
else {
var proptypeGeneric = prop.PropertyType;
var proptypeGeneric = readType;
if (proptypeGeneric.IsNullableType()) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
if (proptypeGeneric.IsEnum ||
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 == true) {
if (trycol?.Attribute.IsPrimary == true) {
ispkExp.Add(
Expression.IfThen(
Expression.AndAlso(
@ -937,17 +951,20 @@ namespace FreeSql.Internal {
}
readExpAssign = Expression.New(RowInfo.Constructor,
GetDataReaderValueBlockExpression(prop.PropertyType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), readpkvalExp }),
GetDataReaderValueBlockExpression(readType, readpkvalExp),
//Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(readType), readpkvalExp }),
Expression.Add(tryidxExp, Expression.Constant(1))
);
} else {
++propIndex;
continue;
//readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), indexesExp, rowExp, tryidxExp });
//readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(readType), indexesExp, rowExp, tryidxExp });
}
}
if (trycol != null && trycol.Attribute.MapType != prop.PropertyType)
ispkExp.Add(Expression.Assign(readExpValue, GetDataReaderValueBlockExpression(prop.PropertyType, readExpValue)));
ispkExp.Add(
Expression.IfThen(
Expression.IsFalse(readpknullExp),
@ -986,7 +1003,7 @@ namespace FreeSql.Internal {
return Expression.Lambda<Func<Type, int[], DbDataReader, int, CommonUtils, RowInfo>>(
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, _commonUtils);
return func(typeOrg, indexes, row, dataIndex, _commonUtils);
}
internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic);
@ -1012,16 +1029,24 @@ namespace FreeSql.Internal {
act(info, value);
}
static BigInteger ToBigInteger(string that) {
if (string.IsNullOrEmpty(that)) return 0;
if (BigInteger.TryParse(that, System.Globalization.NumberStyles.Any, null, out var trybigint)) return trybigint;
return 0;
}
static string ToStringConcat(object obj) {
if (obj == null) return null;
return string.Concat(obj);
}
static ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>> _dicGetDataReaderValue = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>>();
static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) });
static MethodInfo MethodArrayGetLength = typeof(Array).GetMethod("GetLength", new[] { typeof(int) });
static MethodInfo MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
static MethodInfo MethodGuidTryParse = typeof(Guid).GetMethod("TryParse", new[] { typeof(string), typeof(Guid).MakeByRefType() });
static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) });
static MethodInfo MethodToString = typeof(string).GetMethod("Concat", new[] { typeof(object) });
static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
static MethodInfo MethodTimeSpanFromSeconds = typeof(TimeSpan).GetMethod("FromSeconds");
static MethodInfo MethodDoubleParse = typeof(double).GetMethod("Parse", new[] { typeof(string) });
static MethodInfo MethodJTokenParse = typeof(JToken).GetMethod("Parse", new[] { typeof(string) });
static MethodInfo MethodJObjectParse = typeof(JObject).GetMethod("Parse", new[] { typeof(string) });
static MethodInfo MethodJArrayParse = typeof(JArray).GetMethod("Parse", new[] { typeof(string) });
@ -1036,8 +1061,11 @@ namespace FreeSql.Internal {
static MethodInfo MethodDoubleTryParse = typeof(double).GetMethod("TryParse", new[] { typeof(string), typeof(double).MakeByRefType() });
static MethodInfo MethodFloatTryParse = typeof(float).GetMethod("TryParse", new[] { typeof(string), typeof(float).MakeByRefType() });
static MethodInfo MethodDecimalTryParse = typeof(decimal).GetMethod("TryParse", new[] { typeof(string), typeof(decimal).MakeByRefType() });
static MethodInfo MethodTimeSpanTryParse = typeof(TimeSpan).GetMethod("TryParse", new[] { typeof(string), typeof(TimeSpan).MakeByRefType() });
static MethodInfo MethodDateTimeTryParse = typeof(DateTime).GetMethod("TryParse", new[] { typeof(string), typeof(DateTime).MakeByRefType() });
static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() });
static MethodInfo MethodToString = typeof(Utils).GetMethod("ToStringConcat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(object) }, null);
static MethodInfo MethodBigIntegerParse = typeof(Utils).GetMethod("ToBigInteger", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(string) }, null);
public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) {
var returnTarget = Expression.Label(typeof(object));
var valueExp = Expression.Variable(typeof(object), "locvalue");
@ -1088,11 +1116,6 @@ namespace FreeSql.Internal {
ParameterExpression tryparseVarExp = null;
switch (type.FullName) {
case "System.Guid":
//return Expression.IfThenElse(
// Expression.TypeEqual(valueExp, type),
// Expression.Return(returnTarget, valueExp),
// Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(valueExp, typeof(string))), typeof(object)))
//);
tryparseExp = Expression.Block(
new[] { tryparseVarExp = Expression.Variable(typeof(Guid)) },
new Expression[] {
@ -1114,12 +1137,24 @@ namespace FreeSql.Internal {
case "Newtonsoft.Json.Linq.JObject": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJObjectParse, Expression.Convert(valueExp, typeof(string))), typeof(JObject)));
case "Newtonsoft.Json.Linq.JArray": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJArrayParse, Expression.Convert(valueExp, typeof(string))), typeof(JArray)));
case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Return(returnTarget, valueExp);
case "System.Numerics.BigInteger": return Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodBigIntegerParse, Expression.Call(MethodToString, valueExp)), typeof(object)));
case "System.TimeSpan":
return Expression.IfThenElse(
Expression.TypeEqual(valueExp, type),
Expression.Return(returnTarget, valueExp),
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodTimeSpanFromSeconds, Expression.Call(MethodDoubleParse, Expression.Call(MethodToString, valueExp))), typeof(object)))
);
ParameterExpression tryparseVarTsExp, valueStrExp;
return Expression.Block(
new[] { tryparseVarExp = Expression.Variable(typeof(double)), tryparseVarTsExp = Expression.Variable(typeof(TimeSpan)), valueStrExp = Expression.Variable(typeof(string)) },
new Expression[] {
Expression.Assign(valueStrExp, Expression.Call(MethodToString, valueExp)),
Expression.IfThenElse(
Expression.IsTrue(Expression.Call(MethodDoubleTryParse, valueStrExp, tryparseVarExp)),
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodTimeSpanFromSeconds, tryparseVarExp), typeof(object))),
Expression.IfThenElse(
Expression.IsTrue(Expression.Call(MethodTimeSpanTryParse, valueStrExp, tryparseVarTsExp)),
Expression.Return(returnTarget, Expression.Convert(tryparseVarTsExp, typeof(object))),
Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object)))
)
)
}
);
case "System.SByte":
tryparseExp = Expression.Block(
new[] { tryparseVarExp = Expression.Variable(typeof(sbyte)) },
@ -1308,16 +1343,22 @@ namespace FreeSql.Internal {
Expression.SwitchCase(tryparseBooleanExp, Expression.Constant(typeof(bool))),
Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type))
);
else if (type == typeof(string))
switchExp = Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object)));
else
switchExp = Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))));
var defaultRetExp = type == typeof(string) ?
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodToString, valueExp), typeof(object))) :
Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))));
return Expression.IfThenElse(
Expression.TypeEqual(valueExp, type),
Expression.Return(returnTarget, valueExp),
Expression.IfThenElse(
Expression.TypeEqual(valueExp, typeof(string)),
switchExp,
Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type))))
defaultRetExp
)
);
};
@ -1345,132 +1386,6 @@ namespace FreeSql.Internal {
return Expression.Lambda<Func<object, object>>(exp, parmExp).Compile();
});
return func(value);
#region oldcode
//var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary<Type, Func<object, object>>()).GetOrAdd(value.GetType(), valueType => {
// var returnTarget = Expression.Label(typeof(object));
// var parmExp = Expression.Parameter(typeof(object), "value");
// if (type.FullName == "System.Byte[]") return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
// if (type.IsArray) {
// var elementType = type.GetElementType();
// if (elementType == valueType.GetElementType()) return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
// var ret = Expression.Variable(type, "ret");
// var arr = Expression.Variable(valueType, "arr");
// var arrlen = Expression.Variable(typeof(int), "arrlen");
// var x = Expression.Variable(typeof(int), "x");
// var readval = Expression.Variable(typeof(object), "readval");
// var label = Expression.Label(typeof(int));
// return Expression.Lambda<Func<object, object>>(
// Expression.Block(
// new[] { ret, arr, arrlen, readval, x },
// Expression.Assign(arr, Expression.TypeAs(parmExp, valueType)),
// Expression.Assign(arrlen, Expression.ArrayLength(arr)),
// Expression.Assign(x, Expression.Constant(0)),
// Expression.Assign(ret, Expression.NewArrayBounds(elementType, arrlen)),
// Expression.Loop(
// Expression.IfThenElse(
// Expression.LessThan(x, arrlen),
// Expression.Block(
// Expression.Assign(readval, Expression.Call(
// MethodGetDataReaderValue,
// Expression.Constant(elementType, typeof(Type)),
// Expression.Convert(Expression.ArrayAccess(arr, x), typeof(object))
// )),
// Expression.IfThenElse(
// Expression.Equal(readval, Expression.Constant(null)),
// Expression.Assign(Expression.ArrayAccess(ret, x), Expression.Default(elementType)),
// Expression.Assign(Expression.ArrayAccess(ret, x), Expression.Convert(readval, elementType))
// ),
// Expression.PostIncrementAssign(x)
// ),
// Expression.Break(label, x)
// ),
// label
// ),
// Expression.Return(returnTarget, ret),
// Expression.Label(returnTarget, Expression.Default(typeof(object)))
// ), parmExp).Compile();
// }
// if (type.IsNullableType()) type = type.GenericTypeArguments.First();
// if (type.IsEnum) return Expression.Lambda<Func<object, object>>(
// Expression.Call(
// MethodEnumParse,
// Expression.Constant(type, typeof(Type)),
// Expression.Call(MethodToString, parmExp),
// Expression.Constant(true, typeof(bool))
// ) , parmExp).Compile();
// switch (type.FullName) {
// case "System.Guid":
// if (valueType != type) return Expression.Lambda<Func<object, object>>(
// Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(parmExp, typeof(string))), typeof(object))
// , parmExp).Compile();
// return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
// case "MygisPoint": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))),
// typeof(MygisPoint)
// ), parmExp).Compile();
// case "MygisLineString": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))),
// typeof(MygisLineString)
// ), parmExp).Compile();
// case "MygisPolygon": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))),
// typeof(MygisPolygon)
// ), parmExp).Compile();
// case "MygisMultiPoint": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))),
// typeof(MygisMultiPoint)
// ), parmExp).Compile();
// case "MygisMultiLineString": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))),
// typeof(MygisMultiLineString)
// ), parmExp).Compile();
// case "MygisMultiPolygon": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))),
// typeof(MygisMultiPolygon)
// ), parmExp).Compile();
// case "Newtonsoft.Json.Linq.JToken": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(typeof(JToken).GetMethod("Parse", new[] { typeof(string) }), Expression.Convert(parmExp, typeof(string))),
// typeof(JToken)
// ), parmExp).Compile();
// case "Newtonsoft.Json.Linq.JObject": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(typeof(JObject).GetMethod("Parse", new[] { typeof(string) }), Expression.Convert(parmExp, typeof(string))),
// typeof(JObject)
// ), parmExp).Compile();
// case "Newtonsoft.Json.Linq.JArray": return Expression.Lambda<Func<object, object>>(
// Expression.TypeAs(
// Expression.Call(typeof(JArray).GetMethod("Parse", new[] { typeof(string) }), Expression.Convert(parmExp, typeof(string))),
// typeof(JArray)
// ), parmExp).Compile();
// case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
// }
// if (type != valueType) {
// if (type.FullName == "System.TimeSpan") return Expression.Lambda<Func<object, object>>(
// Expression.Convert(Expression.Call(
// MethodTimeSpanFromSeconds,
// Expression.Call(MethodDoubleParse, Expression.Call(MethodToString, parmExp))
// ), typeof(object)), parmExp).Compile();
// return Expression.Lambda<Func<object, object>>(
// Expression.Call(MethodConvertChangeType, parmExp, Expression.Constant(type, typeof(Type)))
// , parmExp).Compile();
// }
// return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
//});
//return func(value);
#endregion
}
internal static object GetDataReaderValue22(Type type, object value) {
if (value == null || value == DBNull.Value) return Activator.CreateInstance(type);

View File

@ -1,280 +0,0 @@
//using FreeSql.DataAnnotations;
//using FreeSql.Internal.Model;
//using Newtonsoft.Json.Linq;
//using Npgsql.LegacyPostgis;
//using NpgsqlTypes;
//using System;
//using System.Collections;
//using System.Collections.Concurrent;
//using System.Collections.Generic;
//using System.Diagnostics;
//using System.Linq;
//using System.Net;
//using System.Net.NetworkInformation;
//using System.Reflection;
//using System.Text.RegularExpressions;
//using System.Threading;
//namespace FreeSql.Internal {
// class UtilsReflection {
// static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>();
// internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
// if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
// if (_cacheGetTableByEntity.TryGetValue($"{common.DbName}-{entity.FullName}", out var trytb)) return trytb; //区分数据库类型缓存
// if (common.CodeFirst.GetDbInfo(entity) != null) return null;
// var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
// trytb = new TableInfo();
// trytb.Type = entity;
// trytb.Properties = entity.GetProperties().ToDictionary(a => a.Name, a => a, StringComparer.CurrentCultureIgnoreCase);
// trytb.CsName = entity.Name;
// trytb.DbName = (tbattr?.Name ?? entity.Name);
// trytb.DbOldName = tbattr?.OldName;
// if (common.CodeFirst.IsSyncStructureToLower) {
// trytb.DbName = trytb.DbName.ToLower();
// trytb.DbOldName = trytb.DbOldName?.ToLower();
// }
// trytb.SelectFilter = tbattr?.SelectFilter;
// foreach (var p in trytb.Properties.Values) {
// var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
// //if (tp == null) continue;
// var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute;
// if (tp == null && colattr == null) continue;
// if (colattr == null)
// colattr = new ColumnAttribute {
// Name = p.Name,
// DbType = tp.Value.dbtypeFull,
// IsIdentity = false,
// IsNullable = tp.Value.isnullable ?? true,
// IsPrimary = false,
// };
// if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)";
// colattr.DbType = colattr.DbType.ToUpper();
// if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false;
// if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
// if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
// if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower();
// if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) {
// colattr.IsNullable = false;
// colattr.DbType += " NOT NULL";
// }
// if (colattr.IsNullable == true && colattr.DbType.Contains("NOT NULL")) colattr.DbType = colattr.DbType.Replace("NOT NULL", "");
// colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => {
// var tmpLt = Regex.Replace(m.Groups[0].Value, @"\s", "");
// if (tmpLt.Contains("CHAR")) tmpLt = tmpLt.Replace("CHAR", " CHAR");
// if (tmpLt.Contains("BYTE")) tmpLt = tmpLt.Replace("BYTE", " BYTE");
// return tmpLt;
// });
// colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type));
// if (colattr.DbDefautValue == null) colattr.DbDefautValue = tp?.defaultValue;
// if (colattr.IsNullable == false && colattr.DbDefautValue == null)
// colattr.DbDefautValue = Activator.CreateInstance(p.PropertyType.IsNullableType() ? p.PropertyType.GenericTypeArguments.FirstOrDefault() : p.PropertyType);
// var col = new ColumnInfo {
// Table = trytb,
// CsName = p.Name,
// CsType = p.PropertyType,
// Attribute = colattr
// };
// trytb.Columns.Add(colattr.Name, col);
// trytb.ColumnsByCs.Add(p.Name, col);
// }
// trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
// if (trytb.Primarys.Any() == false) {
// trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsIdentity == true).ToArray();
// foreach(var col in trytb.Primarys)
// col.Attribute.IsPrimary = true;
// }
// _cacheGetTableByEntity.TryAdd(entity.FullName, trytb);
// return trytb;
// }
// internal static T[] GetDbParamtersByObject<T>(string sql, object obj, string paramPrefix, Func<string, Type, object, T> constructorParamter) {
// if (string.IsNullOrEmpty(sql) || obj == null) return new T[0];
// var ttype = typeof(T);
// var type = obj.GetType();
// if (type == ttype) return new[] { (T)Convert.ChangeType(obj, type) };
// var ret = new List<T>();
// var ps = type.GetProperties();
// foreach (var p in ps) {
// if (sql.IndexOf($"{paramPrefix}{p.Name}", StringComparison.CurrentCultureIgnoreCase) == -1) continue;
// var pvalue = p.GetValue(obj);
// if (p.PropertyType == ttype) ret.Add((T)Convert.ChangeType(pvalue, ttype));
// else ret.Add(constructorParamter(p.Name, p.PropertyType, pvalue));
// }
// return ret.ToArray();
// }
// static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
// [typeof(bool)] = true,
// [typeof(sbyte)] = true,
// [typeof(short)] = true,
// [typeof(int)] = true,
// [typeof(long)] = true,
// [typeof(byte)] = true,
// [typeof(ushort)] = true,
// [typeof(uint)] = true,
// [typeof(ulong)] = true,
// [typeof(double)] = true,
// [typeof(float)] = true,
// [typeof(decimal)] = true,
// [typeof(TimeSpan)] = true,
// [typeof(DateTime)] = true,
// [typeof(DateTimeOffset)] = true,
// [typeof(byte[])] = true,
// [typeof(string)] = true,
// [typeof(Guid)] = true,
// [typeof(MygisPoint)] = true,
// [typeof(MygisLineString)] = true,
// [typeof(MygisPolygon)] = true,
// [typeof(MygisMultiPoint)] = true,
// [typeof(MygisMultiLineString)] = true,
// [typeof(MygisMultiPolygon)] = true,
// [typeof(BitArray)] = true,
// [typeof(NpgsqlPoint)] = true,
// [typeof(NpgsqlLine)] = true,
// [typeof(NpgsqlLSeg)] = true,
// [typeof(NpgsqlBox)] = true,
// [typeof(NpgsqlPath)] = true,
// [typeof(NpgsqlPolygon)] = true,
// [typeof(NpgsqlCircle)] = true,
// [typeof((IPAddress Address, int Subnet))] = true,
// [typeof(IPAddress)] = true,
// [typeof(PhysicalAddress)] = true,
// [typeof(NpgsqlRange<int>)] = true,
// [typeof(NpgsqlRange<long>)] = true,
// [typeof(NpgsqlRange<decimal>)] = true,
// [typeof(NpgsqlRange<DateTime>)] = true,
// [typeof(PostgisPoint)] = true,
// [typeof(PostgisLineString)] = true,
// [typeof(PostgisPolygon)] = true,
// [typeof(PostgisMultiPoint)] = true,
// [typeof(PostgisMultiLineString)] = true,
// [typeof(PostgisMultiPolygon)] = true,
// [typeof(PostgisGeometry)] = true,
// [typeof(PostgisGeometryCollection)] = true,
// [typeof(Dictionary<string, string>)] = true,
// [typeof(JToken)] = true,
// [typeof(JObject)] = true,
// [typeof(JArray)] = 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) {
// if (type.IsArray) return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
// var typeGeneric = type;
// if (typeGeneric.IsNullableType()) typeGeneric = type.GenericTypeArguments.First();
// if (typeGeneric.IsEnum ||
// dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
// return (GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
// if (type.Namespace == "System" && (type.FullName == "System.String" || type.IsValueType)) { //值类型,或者元组
// bool isTuple = type.Name.StartsWith("ValueTuple`");
// if (isTuple) {
// if (_dicTupleConstructor.TryGetValue(type, out var tupleInfo) == false) {
// var types = type.GetFields().Select(a => a.FieldType).ToArray();
// tupleInfo = new _dicTupleConstructorInfo { Constructor = type.GetConstructor(types), Types = types };
// _dicTupleConstructor.AddOrUpdate(type, tupleInfo, (t2, c2) => tupleInfo);
// }
// 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;
// parms[a] = read.value;
// }
// return (tupleInfo.Constructor?.Invoke(parms), dataIndex);
// }
// return (dataIndex >= row.Length || (row[dataIndex] ?? DBNull.Value) == DBNull.Value ? null : GetDataReaderValue(type, row[dataIndex]), dataIndex + 1);
// }
// if (type == typeof(object) && names != null) {
// dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
// var expandodic = (IDictionary<string, object>)expando;
// foreach (var name in names)
// expandodic.Add(name.Key, row[name.Value]);
// return (expando, names.Count);
// }
// //类注入属性
// if (_dicClassConstructor.TryGetValue(type, out var classInfo)== false) {
// classInfo = new _dicClassConstructorInfo { Constructor = type.GetConstructor(new Type[0]), Properties = type.GetProperties() };
// _dicClassConstructor.TryAdd(type, classInfo);
// }
// var value = classInfo.Constructor.Invoke(new object[0]);
// foreach(var prop in classInfo.Properties) {
// var tryidx = dataIndex;
// if (names != null && names.TryGetValue(prop.Name, out tryidx) == false) continue;
// var read = ExecuteArrayRowReadClassOrTuple(prop.PropertyType, names, row, tryidx);
// if (read.dataIndex > dataIndex) dataIndex = read.dataIndex;
// prop.SetValue(value, read.value, null);
// //FillPropertyValue(value, p.Name, read.value);
// //p.SetValue(value, read.value);
// }
// return (value, dataIndex);
// }
// internal static void FillPropertyValue(object info, string memberAccessPath, object value) {
// var current = info;
// PropertyInfo prop = null;
// var members = memberAccessPath.Split('.');
// for (var a = 0; a < members.Length; a++) {
// var type = current.GetType();
// prop = type.GetProperty(members[a], BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
// if (prop == null) throw new Exception(string.Concat(type.FullName, " 没有定义属性 ", members[a]));
// if (a < members.Length - 1) current = prop.GetValue(current);
// }
// prop.SetValue(current, GetDataReaderValue(prop.PropertyType, value), null);
// }
// internal static object GetDataReaderValue(Type type, object value) {
// if (value == null || value == DBNull.Value) return null;
// if (type.FullName == "System.Byte[]") return value;
// if (type.IsArray) {
// var elementType = type.GetElementType();
// var valueArr = value as Array;
// if (elementType == valueArr.GetType().GetElementType()) return value;
// var len = valueArr.GetLength(0);
// var ret = Array.CreateInstance(elementType, len);
// for (var a = 0; a < len; a++) {
// var item = valueArr.GetValue(a);
// ret.SetValue(GetDataReaderValue(elementType, item), a);
// }
// return ret;
// }
// if (type.IsNullableType()) type = type.GenericTypeArguments.First();
// if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true);
// switch(type.FullName) {
// case "System.Guid":
// if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty;
// return value;
// case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint;
// case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString;
// case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon;
// case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint;
// case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString;
// case "MygisMultiPolygon": return MygisMultiPolygon.Parse(string.Concat(value)) as MygisMultiPolygon;
// case "Newtonsoft.Json.Linq.JToken": return JToken.Parse(string.Concat(value));
// case "Newtonsoft.Json.Linq.JObject": return JObject.Parse(string.Concat(value));
// case "Newtonsoft.Json.Linq.JArray": return JArray.Parse(string.Concat(value));
// case "Npgsql.LegacyPostgis.PostgisGeometry": return value;
// }
// if (type != value.GetType()) {
// if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString()));
// return Convert.ChangeType(value, type);
// }
// return value;
// }
// internal static string GetCsName(string name) {
// name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_");
// return char.IsLetter(name, 0) ? name : string.Concat("_", name);
// }
// }
//}

View File

@ -21,7 +21,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());
@ -38,7 +38,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());

View File

@ -41,7 +41,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
return _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);
@ -56,7 +56,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
return await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);

View File

@ -30,7 +30,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -47,7 +47,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -57,14 +57,14 @@ namespace FreeSql.MySql.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) {
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
return;
}
caseWhen.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(", ");
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
++pkidx;
}
caseWhen.Append(")");
@ -72,14 +72,14 @@ namespace FreeSql.MySql.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) {
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d)));
return;
}
sb.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(", ");
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)));
++pkidx;
}
sb.Append(")");

View File

@ -24,14 +24,16 @@ namespace FreeSql.MySql {
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param) {
public override object AddslashesProcessParam(object param, Type mapType) {
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string || param is char)
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
else if (param is Enum)
return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)param).ToInt64();
return string.Concat("'", param.ToString().Replace("'", "''"), "'"); //((Enum)val).ToInt64();
else if (decimal.TryParse(string.Concat(param), out var trydec))
return param;
else if (param is DateTime || param is DateTime?)
@ -43,11 +45,10 @@ namespace FreeSql.MySql {
else if (param is IEnumerable) {
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z));
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
//if (param is string) return string.Concat('N', nparms[a]);
}
protected override DbCommand CreateCommand() {

View File

@ -12,8 +12,8 @@ namespace FreeSql.MySql {
public MySqlExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.NodeType) {
case ExpressionType.Convert:
var operandExp = (exp as UnaryExpression)?.Operand;
@ -132,20 +132,20 @@ namespace FreeSql.MySql {
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Length": return $"char_length({left})";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "now()";
@ -156,7 +156,7 @@ namespace FreeSql.MySql {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Date": return $"cast(date_format({left},'%Y-%m-%d') as datetime)";
case "TimeOfDay": return $"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})";
@ -173,7 +173,7 @@ namespace FreeSql.MySql {
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Zero": return "0";
@ -182,7 +182,7 @@ namespace FreeSql.MySql {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})";
case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)";
@ -199,8 +199,8 @@ namespace FreeSql.MySql {
return null;
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "IsNullOrEmpty":
@ -272,8 +272,8 @@ namespace FreeSql.MySql {
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.Method.Name) {
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
@ -298,8 +298,8 @@ namespace FreeSql.MySql {
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
@ -341,8 +341,8 @@ namespace FreeSql.MySql {
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))";
@ -371,8 +371,8 @@ namespace FreeSql.MySql {
}
throw new Exception($"MySqlExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))";

View File

@ -49,6 +49,12 @@ namespace FreeSql.MySql {
return nametrim; //原生SQL
return $"`{nametrim.Trim('`').Replace(".", "`.`")}`";
}
internal override string TrimQuoteSqlName(string name) {
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}";
}
internal override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
internal override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})";

View File

@ -60,17 +60,14 @@ namespace FreeSql.Oracle.Curd {
foreach (var col in _table.Columns.Values) {
if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name) == false) {
if (colidx2 > 0) sb.Append(", ");
object val = null;
if (_table.Properties.TryGetValue(col.CsName, out var tryp)) {
val = tryp.GetValue(d);
if (col.Attribute.IsPrimary && (col.CsType == typeof(Guid) || col.CsType == typeof(Guid?))
&& (val == null || (Guid)val == Guid.Empty)) tryp.SetValue(d, val = FreeUtil.NewMongodbId());
}
object val = col.GetMapValue(d);
if (col.Attribute.IsPrimary && col.Attribute.MapType.NullableTypeOrThis() == typeof(Guid) && (val == null || (Guid)val == Guid.Empty))
col.SetMapValue(d, val = FreeUtil.NewMongodbId());
if (_noneParameter)
sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.CsType, val));
sb.Append(_commonUtils.GetNoneParamaterSqlValue(specialParams, col.Attribute.MapType, val));
else {
sb.Append(_commonUtils.QuoteWriteParamter(col.CsType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}")));
_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.CsType, val);
sb.Append(_commonUtils.QuoteWriteParamter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}")));
_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col.Attribute.MapType, val);
}
++colidx2;
}
@ -92,7 +89,7 @@ namespace FreeSql.Oracle.Curd {
return 0;
}
var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name);
var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter;
var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter;
identParam.Direction = ParameterDirection.Output;
_orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray());
return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;
@ -106,7 +103,7 @@ namespace FreeSql.Oracle.Curd {
return 0;
}
var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name);
var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter;
var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.Attribute.MapType, 0) as OracleParameter;
identParam.Direction = ParameterDirection.Output;
await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray());
return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0;

View File

@ -30,14 +30,14 @@ namespace FreeSql.Oracle.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) {
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
return;
}
caseWhen.Append("(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(" || ");
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
++pkidx;
}
caseWhen.Append(")");
@ -45,14 +45,14 @@ namespace FreeSql.Oracle.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) {
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d)));
return;
}
sb.Append("(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(" || ");
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)));
++pkidx;
}
sb.Append(")");

View File

@ -23,8 +23,10 @@ namespace FreeSql.Oracle {
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param) {
public override object AddslashesProcessParam(object param, Type mapType) {
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string || param is char)
@ -40,7 +42,7 @@ namespace FreeSql.Oracle {
else if (param is IEnumerable) {
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z));
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");

View File

@ -12,8 +12,8 @@ namespace FreeSql.Oracle {
public OracleExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.NodeType) {
case ExpressionType.Convert:
var operandExp = (exp as UnaryExpression)?.Operand;
@ -132,20 +132,20 @@ namespace FreeSql.Oracle {
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Length": return $"length({left})";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "systimestamp";
@ -156,7 +156,7 @@ namespace FreeSql.Oracle {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Date": return $"trunc({left})";
case "TimeOfDay": return $"({left}-trunc({left}))";
@ -173,7 +173,7 @@ namespace FreeSql.Oracle {
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Zero": return "numtodsinterval(0,'second')";
@ -182,7 +182,7 @@ namespace FreeSql.Oracle {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Days": return $"extract(day from {left})";
case "Hours": return $"extract(hour from {left})";
@ -199,8 +199,8 @@ namespace FreeSql.Oracle {
return null;
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "IsNullOrEmpty":
@ -272,8 +272,8 @@ namespace FreeSql.Oracle {
}
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.Method.Name) {
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
@ -299,8 +299,8 @@ namespace FreeSql.Oracle {
}
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))";
@ -342,8 +342,8 @@ namespace FreeSql.Oracle {
}
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))";
@ -372,8 +372,8 @@ namespace FreeSql.Oracle {
}
throw new Exception($"OracleExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
//case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))";

View File

@ -44,6 +44,12 @@ namespace FreeSql.Oracle {
return nametrim; //原生SQL
return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\"";
}
internal override string TrimQuoteSqlName(string name) {
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}";
}
internal override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"nvl({sql}, {value})";
internal override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";

View File

@ -21,7 +21,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());
@ -38,7 +38,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());

View File

@ -53,7 +53,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
return _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);
@ -68,7 +68,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
return await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);

View File

@ -30,7 +30,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -47,7 +47,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -57,14 +57,14 @@ namespace FreeSql.PostgreSQL.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) {
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
return;
}
caseWhen.Append("(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(" || ");
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar");
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar");
++pkidx;
}
caseWhen.Append(")");
@ -72,14 +72,14 @@ namespace FreeSql.PostgreSQL.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) {
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d)));
return;
}
sb.Append("(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(" || ");
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null)).Append("::varchar");
sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append("::varchar");
++pkidx;
}
sb.Append(")");

View File

@ -26,9 +26,11 @@ namespace FreeSql.PostgreSQL {
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param) {
bool isdic = false;
public override object AddslashesProcessParam(object param, Type mapType) {
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
bool isdic = false;
if (param is bool || param is bool?)
return (bool)param ? "'t'" : "'f'";
else if (param is string || param is char)
@ -57,12 +59,10 @@ namespace FreeSql.PostgreSQL {
} else if (param is IEnumerable) {
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z));
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}else {
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
//if (param is string) return string.Concat('N', nparms[a]);
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
}
protected override DbCommand CreateCommand() {

View File

@ -13,8 +13,8 @@ namespace FreeSql.PostgreSQL {
public PostgreSQLExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.NodeType) {
case ExpressionType.Convert:
var operandExp = (exp as UnaryExpression)?.Operand;
@ -227,20 +227,20 @@ namespace FreeSql.PostgreSQL {
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Length": return $"char_length({left})";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "current_timestamp";
@ -251,7 +251,7 @@ namespace FreeSql.PostgreSQL {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Date": return $"({left})::date";
case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)";
@ -268,7 +268,7 @@ namespace FreeSql.PostgreSQL {
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Zero": return "0";
@ -277,7 +277,7 @@ namespace FreeSql.PostgreSQL {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})";
case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)";
@ -294,8 +294,8 @@ namespace FreeSql.PostgreSQL {
return null;
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "IsNullOrEmpty":
@ -369,8 +369,8 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.Method.Name) {
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
@ -395,8 +395,8 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)";
@ -438,8 +438,8 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))";
@ -468,8 +468,8 @@ namespace FreeSql.PostgreSQL {
}
throw new Exception($"PostgreSQLExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))";

View File

@ -103,6 +103,12 @@ namespace FreeSql.PostgreSQL {
return nametrim; //原生SQL
return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\"";
}
internal override string TrimQuoteSqlName(string name) {
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}";
}
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"coalesce({sql}, {value})";
internal override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";

View File

@ -21,7 +21,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
@ -43,7 +43,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}

View File

@ -44,7 +44,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
@ -64,7 +64,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}

View File

@ -30,7 +30,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
@ -52,7 +52,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0;
foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
sb.Append(_commonUtils.QuoteReadColumn(col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName));
++colidx;
}
@ -68,14 +68,14 @@ namespace FreeSql.SqlServer.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) {
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
return;
}
caseWhen.Append("(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(", ");
caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)");
caseWhen.Append("cast(").Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)");
++pkidx;
}
caseWhen.Append(")");
@ -83,13 +83,13 @@ namespace FreeSql.SqlServer.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) {
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d)));
return;
}
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(", ");
sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null)).Append(" as varchar)");
sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d))).Append(" as varchar)");
++pkidx;
}
}

View File

@ -23,8 +23,10 @@ namespace FreeSql.SqlServer {
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param) {
public override object AddslashesProcessParam(object param, Type mapType) {
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string || param is char)
@ -39,18 +41,16 @@ namespace FreeSql.SqlServer {
} else if (param is DateTimeOffset || param is DateTimeOffset?) {
if (param.Equals(DateTimeOffset.MinValue) == true) param = new DateTimeOffset(new DateTime(1970, 1, 1), TimeSpan.Zero);
return string.Concat("'", ((DateTimeOffset)param).ToString("yyyy-MM-dd HH:mm:ss.fff zzzz"), "'");
}
else if (param is TimeSpan || param is TimeSpan?)
} else if (param is TimeSpan || param is TimeSpan?)
return ((TimeSpan)param).TotalSeconds;
else if (param is IEnumerable) {
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z));
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
} else {
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
//if (param is string) return string.Concat('N', nparms[a]);
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
//if (param is string) return string.Concat('N', nparms[a]);
}
protected override DbCommand CreateCommand() {

View File

@ -12,8 +12,8 @@ namespace FreeSql.SqlServer {
public SqlServerExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.NodeType) {
case ExpressionType.Convert:
var operandExp = (exp as UnaryExpression)?.Operand;
@ -135,20 +135,20 @@ namespace FreeSql.SqlServer {
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Length": return $"len({left})";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "getdate()";
@ -159,7 +159,7 @@ namespace FreeSql.SqlServer {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Date": return $"convert(char(10),{left},120)";
case "TimeOfDay": return $"datediff(second, convert(char(10),{left},120), {left})";
@ -176,7 +176,7 @@ namespace FreeSql.SqlServer {
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Zero": return "0";
@ -185,7 +185,7 @@ namespace FreeSql.SqlServer {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Days": return $"floor(({left})/{60 * 60 * 24})";
case "Hours": return $"floor(({left})/{60 * 60}%24)";
@ -202,8 +202,8 @@ namespace FreeSql.SqlServer {
return null;
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "IsNullOrEmpty":
@ -257,8 +257,8 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.Method.Name) {
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
@ -283,8 +283,8 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))";
@ -326,8 +326,8 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))";
@ -356,8 +356,8 @@ namespace FreeSql.SqlServer {
}
throw new Exception($"SqlServerExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))";

View File

@ -41,6 +41,12 @@ namespace FreeSql.SqlServer {
return nametrim; //原生SQL
return $"[{nametrim.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]";
}
internal override string TrimQuoteSqlName(string name) {
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}";
}
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"isnull({sql}, {value})";
internal override string StringConcat(string[] objs, Type[] types) {

View File

@ -30,14 +30,14 @@ namespace FreeSql.Sqlite.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) {
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().Attribute.MapType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name)));
return;
}
caseWhen.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(", ");
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
caseWhen.Append(_commonUtils.QuoteReadColumn(pk.Attribute.MapType, _commonUtils.QuoteSqlName(pk.Attribute.Name)));
++pkidx;
}
caseWhen.Append(")");
@ -45,14 +45,14 @@ namespace FreeSql.Sqlite.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) {
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", _table.Primarys.First().GetMapValue(d)));
return;
}
sb.Append("CONCAT(");
var pkidx = 0;
foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(", ");
sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null));
sb.Append(_commonUtils.FormatSql("{0}", pk.GetMapValue(d)));
++pkidx;
}
sb.Append(")");

View File

@ -23,8 +23,10 @@ namespace FreeSql.Sqlite {
}
}
static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param) {
public override object AddslashesProcessParam(object param, Type mapType) {
if (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?)
return (bool)param ? 1 : 0;
else if (param is string || param is char)
@ -40,11 +42,10 @@ namespace FreeSql.Sqlite {
else if (param is IEnumerable) {
var sb = new StringBuilder();
var ie = param as IEnumerable;
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z));
foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z, mapType));
return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString();
}
return string.Concat("'", param.ToString().Replace("'", "''"), "'");
//if (param is string) return string.Concat('N', nparms[a]);
}
protected override DbCommand CreateCommand() {

View File

@ -12,8 +12,8 @@ namespace FreeSql.Sqlite {
public SqliteExpression(CommonUtils common) : base(common) { }
internal override string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.NodeType) {
case ExpressionType.Convert:
var operandExp = (exp as UnaryExpression)?.Operand;
@ -132,20 +132,20 @@ namespace FreeSql.Sqlite {
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Empty": return "''";
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Length": return $"length({left})";
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Now": return "datetime(current_timestamp,'localtime')";
@ -156,7 +156,7 @@ namespace FreeSql.Sqlite {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Date": return $"date({left})";
case "TimeOfDay": return $"strftime('%s',{left})";
@ -173,7 +173,7 @@ namespace FreeSql.Sqlite {
}
return null;
}
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
internal override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) {
if (exp.Expression == null) {
switch (exp.Member.Name) {
case "Zero": return "0";
@ -182,7 +182,7 @@ namespace FreeSql.Sqlite {
}
return null;
}
var left = ExpressionLambdaToSql(exp.Expression, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
var left = ExpressionLambdaToSql(exp.Expression, tsc);
switch (exp.Member.Name) {
case "Days": return $"floor(({left})/{60 * 60 * 24})";
case "Hours": return $"floor(({left})/{60 * 60}%24)";
@ -199,8 +199,8 @@ namespace FreeSql.Sqlite {
return null;
}
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "IsNullOrEmpty":
@ -277,8 +277,8 @@ namespace FreeSql.Sqlite {
}
throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
switch (exp.Method.Name) {
case "Abs": return $"abs({getExp(exp.Arguments[0])})";
case "Sign": return $"sign({getExp(exp.Arguments[0])})";
@ -303,8 +303,8 @@ namespace FreeSql.Sqlite {
}
throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"(strftime('%s',{getExp(exp.Arguments[0])}) -strftime('%s',{getExp(exp.Arguments[1])}))";
@ -346,8 +346,8 @@ namespace FreeSql.Sqlite {
}
throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))";
@ -376,8 +376,8 @@ namespace FreeSql.Sqlite {
}
throw new Exception($"SqliteExpression 未实现函数表达式 {exp} 解析");
}
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) {
Func<Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);
if (exp.Object == null) {
switch (exp.Method.Name) {
case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))";

View File

@ -59,6 +59,12 @@ namespace FreeSql.Sqlite {
return nametrim; //原生SQL
return $"\"{nametrim.Trim('"').Replace(".", "\".\"")}\"";
}
internal override string TrimQuoteSqlName(string name) {
var nametrim = name.Trim();
if (nametrim.StartsWith("(") && nametrim.EndsWith(")"))
return nametrim; //原生SQL
return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}";
}
internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}";
internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})";
internal override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}";