diff --git a/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs b/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs index 7a8929d4..04939deb 100644 --- a/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs +++ b/FreeSql.Tests/ExpressionTree/GetDataReaderValueBlockExpressionTest.cs @@ -13,6 +13,38 @@ using System.Linq.Expressions; namespace FreeSql.ExpressionTree { public class GetDataReaderValueBlockExpressionTest { + [Fact] + public void Guid2() { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.Empty)); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), Guid.Empty)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.NewGuid())); + var newguid = Guid.NewGuid(); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid), newguid)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(null)); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), null)); + + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(Guid.Empty)); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid?), Guid.Empty)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(newguid)); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid?), newguid)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(Guid?), null)); + + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(Guid.Empty.ToString())); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), Guid.Empty.ToString())); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant(newguid.ToString())); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid), newguid.ToString())); + var exp333 = Utils.GetDataReaderValueBlockExpression(typeof(Guid), Expression.Constant("-1")); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid), "-1")); + + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(Guid.Empty.ToString())); + Assert.Equal(Guid.Empty, Utils.GetDataReaderValue(typeof(Guid?), Guid.Empty.ToString())); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant(newguid.ToString())); + Assert.Equal(newguid, Utils.GetDataReaderValue(typeof(Guid?), newguid.ToString())); + var exp3333 = Utils.GetDataReaderValueBlockExpression(typeof(Guid?), Expression.Constant("-1")); + Assert.Null(Utils.GetDataReaderValue(typeof(Guid?), "-1")); + } + [Fact] public void Boolean() { var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(true)); @@ -342,5 +374,59 @@ namespace FreeSql.ExpressionTree { var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant("aaa")); Assert.Null(Utils.GetDataReaderValue(typeof(decimal?), "aaa")); } + + [Fact] + public void DateTime2() { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTime.MinValue)); + Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime), DateTime.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(DateTime.MaxValue)); + Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime), DateTime.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("2000-1-1")); + Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime), "2000-1-1")); + + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTime.MinValue)); + Assert.Equal(DateTime.MinValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTime.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(DateTime.MaxValue)); + Assert.Equal(DateTime.MaxValue, Utils.GetDataReaderValue(typeof(DateTime?), DateTime.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("2000-1-1")); + Assert.Equal(DateTime.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTime?), "2000-1-1")); + + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant(null)); + Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime), Expression.Constant("aaa")); + Assert.Equal(default(DateTime), Utils.GetDataReaderValue(typeof(DateTime), "aaa")); + + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTime?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTime?), "aaa")); + } + + [Fact] + public void DateTimeOffset2() { + var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTimeOffset.MinValue)); + Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTimeOffset.MinValue)); + var exp2 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(DateTimeOffset.MaxValue)); + Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset), DateTimeOffset.MaxValue)); + var exp3 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("2000-1-1")); + Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset), "2000-1-1")); + + var exp11 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTimeOffset.MinValue)); + Assert.Equal(DateTimeOffset.MinValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTimeOffset.MinValue)); + var exp22 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(DateTimeOffset.MaxValue)); + Assert.Equal(DateTimeOffset.MaxValue, Utils.GetDataReaderValue(typeof(DateTimeOffset?), DateTimeOffset.MaxValue)); + var exp33 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("2000-1-1")); + Assert.Equal(DateTimeOffset.Parse("2000-1-1"), Utils.GetDataReaderValue(typeof(DateTimeOffset?), "2000-1-1")); + + var exp111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant(null)); + Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), null)); + var exp222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset), Expression.Constant("aaa")); + Assert.Equal(default(DateTimeOffset), Utils.GetDataReaderValue(typeof(DateTimeOffset), "aaa")); + + var exp1111 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant(null)); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), null)); + var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(DateTimeOffset?), Expression.Constant("aaa")); + Assert.Null(Utils.GetDataReaderValue(typeof(DateTimeOffset?), "aaa")); + } } } diff --git a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs index 40078a45..4c0ce913 100644 --- a/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs +++ b/FreeSql.Tests/Sqlite/Curd/SqliteSelectTest.cs @@ -126,19 +126,36 @@ namespace FreeSql.Tests.Sqlite { public int id { get; set; } public string name { get; set; } //这是join表的属性 public int ParentId { get; set; } //这是join表的属性 + + public bool? testBool1 { get; set; } + public bool? testBool2 { get; set; } + } + class TestDtoLeftJoin { + [Column(IsPrimary = true)] + public int Guid { get; set; } + public bool? testBool1 { get; set; } + public bool? testBool2 { get; set; } } [Fact] public void ToList() { + g.sqlite.Delete().Where("1=1").ExecuteAffrows(); + var testlist = select.Limit(10).ToList(); + foreach(var testitem in testlist) { + var testdtolj = new TestDtoLeftJoin { Guid = testitem.TypeGuid, testBool1 = true }; + if (g.sqlite.Select().Where(a => a.Guid == testitem.TypeGuid).Any() == false) + g.sqlite.Insert(testdtolj).ExecuteAffrows(); + } + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); var testDto2 = select.Limit(10).ToList(a => new TestDto()); var testDto3 = select.Limit(10).ToList(a => new TestDto { }); var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); - var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); - var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); - var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); - var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto11 = select.LeftJoin((a,b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); g.sqlite.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); var testGuidId5 = g.sqlite.Select().ToList(); diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 5824cea6..1ae14635 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -140,6 +140,43 @@ namespace FreeSql.Extensions.EntityUtil { }); return func(entity); } + static ConcurrentDictionary>>> _dicGetEntityValueWithPropertyName = new ConcurrentDictionary>>>(); + /// + /// 获取实体的属性值 + /// + /// + /// + /// + /// + //public static object GetEntityValueWithPropertyName(this IFreeSql orm, TEntity entity, string propertyName) => GetEntityKeyValues(orm, typeof(TEntity), entity, propertyName); + public static object GetEntityValueWithPropertyName(this IFreeSql orm, Type entityType, object entity, string propertyName) { + if (entity == null) return null; + if (entityType == null) entityType = entity.GetType(); + var func = _dicGetEntityValueWithPropertyName + .GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>>()) + .GetOrAdd(entityType, et => new ConcurrentDictionary>()) + .GetOrAdd(propertyName, pn => { + var _table = orm.CodeFirst.GetTableByEntity(entityType); + var pks = _table.Primarys; + var returnTarget = Expression.Label(typeof(object)); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(entityType); + var var2Ret = Expression.Variable(typeof(object)); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, entityType)), + Expression.Assign( + var2Ret, + Expression.Convert(Expression.MakeMemberAccess(var1Parm, _table.Properties[pn]), typeof(object)) + ) + }); + exps.AddRange(new Expression[] { + Expression.Return(returnTarget, var2Ret), + Expression.Label(returnTarget, Expression.Default(typeof(object))) + }); + return Expression.Lambda>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile(); + }); + return func(entity); + } static ConcurrentDictionary>> _dicGetEntityString = new ConcurrentDictionary>>(); /// /// 获取实体的所有数据,以 (1, 2, xxx) 的形式 diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index eee11a9c..fc807fa5 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.5.1 + 0.5.1.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 36a52058..b935ab23 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -311,6 +311,7 @@ namespace FreeSql.Internal { 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.TypeAs: case ExpressionType.Convert: //var othercExp = ExpressionLambdaToSqlOther(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); //if (string.IsNullOrEmpty(othercExp) == false) return othercExp; @@ -487,7 +488,7 @@ namespace FreeSql.Internal { } var tmpExp = Expression.Equal(pexp1, pexp2); if (mn == 0) manySubSelectWhereExp = tmpExp; - else manySubSelectWhereExp = Expression.And(manySubSelectWhereExp, tmpExp); + else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp); } var manySubSelectExpBoy = Expression.Call( manySubSelectAsSelectExp, @@ -509,7 +510,7 @@ namespace FreeSql.Internal { } var tmpExp = Expression.Equal(pexp1, pexp2); if (mn == 0) fsqlManyWhereExp = tmpExp; - else fsqlManyWhereExp = Expression.And(fsqlManyWhereExp, tmpExp); + else fsqlManyWhereExp = Expression.AndAlso(fsqlManyWhereExp, tmpExp); } fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent }); fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); @@ -532,7 +533,7 @@ namespace FreeSql.Internal { } var tmpExp = Expression.Equal(pexp1, pexp2); if (mn == 0) fsqlWhereExp = tmpExp; - else fsqlWhereExp = Expression.And(fsqlWhereExp, tmpExp); + else fsqlWhereExp = Expression.AndAlso(fsqlWhereExp, tmpExp); } fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) }); } @@ -592,6 +593,15 @@ namespace FreeSql.Internal { exp2 = callExp.Object; if (exp2 == null) break; continue; + case ExpressionType.TypeAs: + case ExpressionType.Convert: + var oper2 = (exp2 as UnaryExpression).Operand; + if (oper2.NodeType == ExpressionType.Parameter) { + var oper2Parm = oper2 as ParameterExpression; + expStack.Push(Expression.Parameter(exp2.Type, oper2Parm.Name)); + } else + expStack.Push(oper2); + break; } break; } @@ -681,7 +691,7 @@ namespace FreeSql.Internal { } var tmpExp = Expression.Equal(pexp1, pexp2); if (mn == 0) navCondExp = tmpExp; - else navCondExp = Expression.And(navCondExp, tmpExp); + else navCondExp = Expression.AndAlso(navCondExp, tmpExp); } if (find.Type == SelectTableInfoType.InnerJoin || find.Type == SelectTableInfoType.LeftJoin || diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 72caee6c..1eba3196 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -343,6 +343,8 @@ namespace FreeSql.Internal { nvref.Columns.Add(trytb.Primarys[a]); nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; if (isLazy) { if (a > 0) lmbdWhere.Append(" && "); @@ -374,6 +376,8 @@ namespace FreeSql.Internal { nvref.RefColumns.Add(tbref.Primarys[a]); nvref.MiddleColumns.Add(trycol); + if (tbmid.Primarys.Any() == false) + trycol.Attribute.IsPrimary = true; if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName); } @@ -382,6 +386,9 @@ namespace FreeSql.Internal { nvref.RefEntityType = tbref.Type; nvref.RefType = TableRefType.ManyToMany; trytb.AddOrUpdateTableRef(pnv.Name, nvref); + + if (tbmid.Primarys.Any() == false) + tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); } if (isLazy) { @@ -819,7 +826,7 @@ namespace FreeSql.Internal { if (typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) && trycol.Attribute.IsPrimary) { ispkExp.Add( Expression.IfThen( - Expression.And( + Expression.AndAlso( Expression.IsFalse(readpknullExp), Expression.Or( Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), @@ -905,7 +912,7 @@ namespace FreeSql.Internal { if (typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) && trycol.Attribute.IsPrimary) { ispkExp.Add( Expression.IfThen( - Expression.And( + Expression.AndAlso( Expression.IsFalse(readpknullExp), Expression.Or( Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), @@ -1000,7 +1007,7 @@ namespace FreeSql.Internal { 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 MethodGuidParse = typeof(Guid).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) }); @@ -1020,6 +1027,8 @@ 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 MethodDateTimeTryParse = typeof(DateTime).GetMethod("TryParse", new[] { typeof(string), typeof(DateTime).MakeByRefType() }); + static MethodInfo MethodDateTimeOffsetTryParse = typeof(DateTimeOffset).GetMethod("TryParse", new[] { typeof(string), typeof(DateTimeOffset).MakeByRefType() }); public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) { var returnTarget = Expression.Label(typeof(object)); var valueExp = Expression.Variable(typeof(object), "locvalue"); @@ -1070,11 +1079,22 @@ 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))) - ); + //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[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodGuidTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; case "MygisPoint": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPoint))); case "MygisLineString": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisLineString))); case "MygisPolygon": return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodMygisGeometryParse, Expression.Convert(valueExp, typeof(string))), typeof(MygisPolygon))); @@ -1223,6 +1243,30 @@ namespace FreeSql.Internal { } ); break; + case "System.DateTime": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(DateTime)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodDateTimeTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; + case "System.DateTimeOffset": + tryparseExp = Expression.Block( + new[] { tryparseVarExp = Expression.Variable(typeof(DateTimeOffset)) }, + new Expression[] { + Expression.IfThenElse( + Expression.IsTrue(Expression.Call(MethodDateTimeOffsetTryParse, Expression.Convert(valueExp, typeof(string)), tryparseVarExp)), + Expression.Return(returnTarget, Expression.Convert(tryparseVarExp, typeof(object))), + Expression.Return(returnTarget, Expression.Convert(Expression.Default(typeOrg), typeof(object))) + ) + } + ); + break; case "System.Boolean": tryparseBooleanExp = Expression.Return(returnTarget, Expression.Convert( @@ -1241,9 +1285,12 @@ namespace FreeSql.Internal { switchExp = Expression.Switch( Expression.Constant(type), Expression.SwitchCase(tryparseExp, + Expression.Constant(typeof(Guid)), Expression.Constant(typeof(sbyte)), Expression.Constant(typeof(short)), Expression.Constant(typeof(int)), Expression.Constant(typeof(long)), Expression.Constant(typeof(byte)), Expression.Constant(typeof(ushort)), Expression.Constant(typeof(uint)), Expression.Constant(typeof(ulong)), - Expression.Constant(typeof(double)), Expression.Constant(typeof(float)), Expression.Constant(typeof(decimal))), + Expression.Constant(typeof(double)), Expression.Constant(typeof(float)), Expression.Constant(typeof(decimal)), + Expression.Constant(typeof(DateTime)), Expression.Constant(typeof(DateTimeOffset)) + ), Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type)) ); else if (tryparseBooleanExp != null)