- 补充 实现表达式转换类型的解析,如:Select<object>().Where(a => (a as 实体类型).Id == 0);

- 完善 ExpressionTree 基础数据类型 TryParse 使用与单元测试;
- 优化 ManyToMany 中间实体未配置主键时,自动配置联合主键;
- 修复 Expression.And 的使用问题;
This commit is contained in:
28810 2019-04-17 22:22:15 +08:00
parent fba0431b7e
commit b33536e4df
6 changed files with 215 additions and 18 deletions

View File

@ -13,6 +13,38 @@ using System.Linq.Expressions;
namespace FreeSql.ExpressionTree { namespace FreeSql.ExpressionTree {
public class GetDataReaderValueBlockExpressionTest { 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] [Fact]
public void Boolean() { public void Boolean() {
var exp1 = Utils.GetDataReaderValueBlockExpression(typeof(bool), Expression.Constant(true)); 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")); var exp2222 = Utils.GetDataReaderValueBlockExpression(typeof(decimal?), Expression.Constant("aaa"));
Assert.Null(Utils.GetDataReaderValue(typeof(decimal?), "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"));
}
} }
} }

View File

@ -126,19 +126,36 @@ namespace FreeSql.Tests.Sqlite {
public int id { get; set; } public int id { get; set; }
public string name { get; set; } //这是join表的属性 public string name { get; set; } //这是join表的属性
public int ParentId { 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] [Fact]
public void ToList() { public void ToList() {
g.sqlite.Delete<TestDtoLeftJoin>().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<TestDtoLeftJoin>().Where(a => a.Guid == testitem.TypeGuid).Any() == false)
g.sqlite.Insert<TestDtoLeftJoin>(testdtolj).ExecuteAffrows();
}
var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); 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 testDto2 = select.Limit(10).ToList(a => new TestDto());
var testDto3 = 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 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 testDto11 = select.LeftJoin<TestDtoLeftJoin>((a,b) => b.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 testDto22 = select.LeftJoin<TestDtoLeftJoin>((a, b) => b.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 testDto33 = select.LeftJoin<TestDtoLeftJoin>((a, b) => b.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 testDto44 = select.LeftJoin<TestDtoLeftJoin>((a, b) => b.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { });
g.sqlite.Insert<TestGuidIdToList>().AppendData(new TestGuidIdToList()).ExecuteAffrows(); g.sqlite.Insert<TestGuidIdToList>().AppendData(new TestGuidIdToList()).ExecuteAffrows();
var testGuidId5 = g.sqlite.Select<TestGuidIdToList>().ToList(); var testGuidId5 = g.sqlite.Select<TestGuidIdToList>().ToList();

View File

@ -140,6 +140,43 @@ namespace FreeSql.Extensions.EntityUtil {
}); });
return func(entity); return func(entity);
} }
static ConcurrentDictionary<DataType, ConcurrentDictionary<Type, ConcurrentDictionary<string, Func<object, object>>>> _dicGetEntityValueWithPropertyName = new ConcurrentDictionary<DataType, ConcurrentDictionary<Type, ConcurrentDictionary<string, Func<object, object>>>>();
/// <summary>
/// 获取实体的属性值
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="_table"></param>
/// <param name="entity"></param>
/// <returns></returns>
//public static object GetEntityValueWithPropertyName<TEntity>(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<Type, ConcurrentDictionary<string, Func<object, object>>>())
.GetOrAdd(entityType, et => new ConcurrentDictionary<string, Func<object, object>>())
.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<Expression>(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<Func<object, object>>(Expression.Block(new[] { var1Parm, var2Ret }, exps), new[] { parm1 }).Compile();
});
return func(entity);
}
static ConcurrentDictionary<DataType, ConcurrentDictionary<Type, Func<object, string>>> _dicGetEntityString = new ConcurrentDictionary<DataType, ConcurrentDictionary<Type, Func<object, string>>>(); static ConcurrentDictionary<DataType, ConcurrentDictionary<Type, Func<object, string>>> _dicGetEntityString = new ConcurrentDictionary<DataType, ConcurrentDictionary<Type, Func<object, string>>>();
/// <summary> /// <summary>
/// 获取实体的所有数据,以 (1, 2, xxx) 的形式 /// 获取实体的所有数据,以 (1, 2, xxx) 的形式

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<Version>0.5.1</Version> <Version>0.5.1.1</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors> <Authors>YeXiangQin</Authors>
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description> <Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>

View File

@ -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.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.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.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
case ExpressionType.TypeAs:
case ExpressionType.Convert: case ExpressionType.Convert:
//var othercExp = ExpressionLambdaToSqlOther(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); //var othercExp = ExpressionLambdaToSqlOther(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style);
//if (string.IsNullOrEmpty(othercExp) == false) return othercExp; //if (string.IsNullOrEmpty(othercExp) == false) return othercExp;
@ -487,7 +488,7 @@ namespace FreeSql.Internal {
} }
var tmpExp = Expression.Equal(pexp1, pexp2); var tmpExp = Expression.Equal(pexp1, pexp2);
if (mn == 0) manySubSelectWhereExp = tmpExp; if (mn == 0) manySubSelectWhereExp = tmpExp;
else manySubSelectWhereExp = Expression.And(manySubSelectWhereExp, tmpExp); else manySubSelectWhereExp = Expression.AndAlso(manySubSelectWhereExp, tmpExp);
} }
var manySubSelectExpBoy = Expression.Call( var manySubSelectExpBoy = Expression.Call(
manySubSelectAsSelectExp, manySubSelectAsSelectExp,
@ -509,7 +510,7 @@ namespace FreeSql.Internal {
} }
var tmpExp = Expression.Equal(pexp1, pexp2); var tmpExp = Expression.Equal(pexp1, pexp2);
if (mn == 0) fsqlManyWhereExp = tmpExp; 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 }); fsqltables.Add(new SelectTableInfo { Alias = manySubSelectWhereParam.Name, Parameter = manySubSelectWhereParam, Table = manyTb, Type = SelectTableInfoType.Parent });
fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) }); fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlManyWhereExp, fsqlWhereParam) });
@ -532,7 +533,7 @@ namespace FreeSql.Internal {
} }
var tmpExp = Expression.Equal(pexp1, pexp2); var tmpExp = Expression.Equal(pexp1, pexp2);
if (mn == 0) fsqlWhereExp = tmpExp; 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) }); fsqlWhere.Invoke(fsql, new object[] { Expression.Lambda(fsqlWhereExp, fsqlWhereParam) });
} }
@ -592,6 +593,15 @@ namespace FreeSql.Internal {
exp2 = callExp.Object; exp2 = callExp.Object;
if (exp2 == null) break; if (exp2 == null) break;
continue; 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; break;
} }
@ -681,7 +691,7 @@ namespace FreeSql.Internal {
} }
var tmpExp = Expression.Equal(pexp1, pexp2); var tmpExp = Expression.Equal(pexp1, pexp2);
if (mn == 0) navCondExp = tmpExp; if (mn == 0) navCondExp = tmpExp;
else navCondExp = Expression.And(navCondExp, tmpExp); else navCondExp = Expression.AndAlso(navCondExp, tmpExp);
} }
if (find.Type == SelectTableInfoType.InnerJoin || if (find.Type == SelectTableInfoType.InnerJoin ||
find.Type == SelectTableInfoType.LeftJoin || find.Type == SelectTableInfoType.LeftJoin ||

View File

@ -343,6 +343,8 @@ namespace FreeSql.Internal {
nvref.Columns.Add(trytb.Primarys[a]); nvref.Columns.Add(trytb.Primarys[a]);
nvref.MiddleColumns.Add(trycol); nvref.MiddleColumns.Add(trycol);
if (tbmid.Primarys.Any() == false)
trycol.Attribute.IsPrimary = true;
if (isLazy) { if (isLazy) {
if (a > 0) lmbdWhere.Append(" && "); if (a > 0) lmbdWhere.Append(" && ");
@ -374,6 +376,8 @@ namespace FreeSql.Internal {
nvref.RefColumns.Add(tbref.Primarys[a]); nvref.RefColumns.Add(tbref.Primarys[a]);
nvref.MiddleColumns.Add(trycol); 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); 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.RefEntityType = tbref.Type;
nvref.RefType = TableRefType.ManyToMany; nvref.RefType = TableRefType.ManyToMany;
trytb.AddOrUpdateTableRef(pnv.Name, nvref); trytb.AddOrUpdateTableRef(pnv.Name, nvref);
if (tbmid.Primarys.Any() == false)
tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
} }
if (isLazy) { if (isLazy) {
@ -819,7 +826,7 @@ namespace FreeSql.Internal {
if (typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) && trycol.Attribute.IsPrimary) { if (typetb.ColumnsByCs.TryGetValue(ctorParm.Name, out var trycol) && trycol.Attribute.IsPrimary) {
ispkExp.Add( ispkExp.Add(
Expression.IfThen( Expression.IfThen(
Expression.And( Expression.AndAlso(
Expression.IsFalse(readpknullExp), Expression.IsFalse(readpknullExp),
Expression.Or( Expression.Or(
Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), 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) { if (typetb.ColumnsByCs.TryGetValue(prop.Name, out var trycol) && trycol.Attribute.IsPrimary) {
ispkExp.Add( ispkExp.Add(
Expression.IfThen( Expression.IfThen(
Expression.And( Expression.AndAlso(
Expression.IsFalse(readpknullExp), Expression.IsFalse(readpknullExp),
Expression.Or( Expression.Or(
Expression.Equal(readpkvalExp, Expression.Constant(DBNull.Value)), 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 MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) });
static MethodInfo MethodArrayGetLength = typeof(Array).GetMethod("GetLength", 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 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 MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) });
static MethodInfo MethodToString = typeof(string).GetMethod("Concat", new[] { typeof(object) }); static MethodInfo MethodToString = typeof(string).GetMethod("Concat", new[] { typeof(object) });
static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }); 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 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 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 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) { public static Expression GetDataReaderValueBlockExpression(Type type, Expression value) {
var returnTarget = Expression.Label(typeof(object)); var returnTarget = Expression.Label(typeof(object));
var valueExp = Expression.Variable(typeof(object), "locvalue"); var valueExp = Expression.Variable(typeof(object), "locvalue");
@ -1070,11 +1079,22 @@ namespace FreeSql.Internal {
ParameterExpression tryparseVarExp = null; ParameterExpression tryparseVarExp = null;
switch (type.FullName) { switch (type.FullName) {
case "System.Guid": case "System.Guid":
return Expression.IfThenElse( //return Expression.IfThenElse(
Expression.TypeEqual(valueExp, type), // Expression.TypeEqual(valueExp, type),
Expression.Return(returnTarget, valueExp), // Expression.Return(returnTarget, valueExp),
Expression.Return(returnTarget, Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(valueExp, typeof(string))), typeof(object))) // 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 "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 "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))); 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; 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": case "System.Boolean":
tryparseBooleanExp = Expression.Return(returnTarget, tryparseBooleanExp = Expression.Return(returnTarget,
Expression.Convert( Expression.Convert(
@ -1241,9 +1285,12 @@ namespace FreeSql.Internal {
switchExp = Expression.Switch( switchExp = Expression.Switch(
Expression.Constant(type), Expression.Constant(type),
Expression.SwitchCase(tryparseExp, 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(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(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)) Expression.SwitchCase(Expression.Return(returnTarget, Expression.Call(MethodConvertChangeType, valueExp, Expression.Constant(type, typeof(Type)))), Expression.Constant(type))
); );
else if (tryparseBooleanExp != null) else if (tryparseBooleanExp != null)