diff --git a/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs b/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..564321e6 --- /dev/null +++ b/FreeSql.Tests/MySql/MapType/BoolNullableTest.cs @@ -0,0 +1,1562 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MySql.MapType { + public class BoolNullableTest { + class BoolNullableMap { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() { + } + [Fact] + public void TimeSpanNullable() { + } + [Fact] + public void DateTime() { + } + [Fact] + public void DateTimeNullable() { + } + + [Fact] + public void ByteArray() { + } + [Fact] + public void String() { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() { + } + [Fact] + public void GuidNullable() { + } + + [Fact] + public void MygisPoint() { + } + [Fact] + public void MygisLineString() { + } + [Fact] + public void MygisPolygon() { + } + [Fact] + public void MygisMultiPoint() { + } + [Fact] + public void MygisMultiLineString() { + } + [Fact] + public void MygisMultiPolygon() { + } + } +} diff --git a/FreeSql.Tests/MySql/MapType/BoolTest.cs b/FreeSql.Tests/MySql/MapType/BoolTest.cs new file mode 100644 index 00000000..19451781 --- /dev/null +++ b/FreeSql.Tests/MySql/MapType/BoolTest.cs @@ -0,0 +1,1096 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.MySql.MapType { + public class BoolTest { + + class BoolMap { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() { + } + [Fact] + public void TimeSpanNullable() { + } + [Fact] + public void DateTime() { + } + [Fact] + public void DateTimeNullable() { + } + + [Fact] + public void ByteArray() { + } + [Fact] + public void String() { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() { + } + [Fact] + public void GuidNullable() { + } + + [Fact] + public void MygisPoint() { + } + [Fact] + public void MygisLineString() { + } + [Fact] + public void MygisPolygon() { + } + [Fact] + public void MygisMultiPoint() { + } + [Fact] + public void MygisMultiLineString() { + } + [Fact] + public void MygisMultiPolygon() { + } + } +} diff --git a/FreeSql.Tests/MySql/MapType/EnumTest.cs b/FreeSql.Tests/MySql/MapType/EnumTest.cs new file mode 100644 index 00000000..d60b03c3 --- /dev/null +++ b/FreeSql.Tests/MySql/MapType/EnumTest.cs @@ -0,0 +1,254 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MySql.MapType { + public class EnumTest { + class EnumTestMap { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/MySql/MapType/ToStringTest.cs b/FreeSql.Tests/MySql/MapType/ToStringTest.cs new file mode 100644 index 00000000..033549d2 --- /dev/null +++ b/FreeSql.Tests/MySql/MapType/ToStringTest.cs @@ -0,0 +1,557 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.MySql.MapType { + public class ToStringTest { + class ToStringMap { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs b/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs index a107ce57..731fa99a 100644 --- a/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs +++ b/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/MathTest.cs @@ -71,7 +71,7 @@ namespace FreeSql.Tests.PostgreSQLExpression { [Fact] public void Log() { var data = new List(); - data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); } [Fact] public void Log10() { diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index a46238d1..17eedaf8 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -46,6 +46,6 @@ namespace FreeSql.DataAnnotations { /// /// 类型映射,比如:可将 enum 属性映射成 typeof(string) /// - public Type Mapping { get; set; } + public Type MapType { get; set; } } } diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index e7b8bd2e..17cc6640 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -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; } + /// + /// 类型映射,比如:可将 enum 属性映射成 typeof(string) + /// + /// + /// + public ColumnFluent MapType(Type type) { + _column.MapType = type; + return this; + } } } diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index f19461ca..f2ea5bd4 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -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>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index f023f2f4..5ad56bc4 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -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 _dicReadAnonymousFieldDtoPropertys = new ConcurrentDictionary(); internal bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func getSelectGroupingMapString) { + Func 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 _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 _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func 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 _tables, Expression exp, bool isQuoteName, Func getSelectGroupingMapString) { @@ -250,9 +276,9 @@ namespace FreeSql.Internal { { ExpressionType.Modulo, "%" }, { ExpressionType.Equal, "=" }, }; - internal string ExpressionWhereLambdaNoneForeignObject(List _tables, List _selectColumnMap, Expression exp, Func getSelectGroupingMapString) { - var sql = ExpressionLambdaToSql(exp, _tables, _selectColumnMap, getSelectGroupingMapString, SelectTableInfoType.From, true, false, ExpressionStyle.Where); - switch(sql) { + internal string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, Func 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 _tables, Expression exp, Func 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 _tables, SelectTableInfoType tbtype, Expression exp, Func 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 _dicExpressionLambdaToSqlAsSelectAnyMethodInfo = new ConcurrentDictionary(); static ConcurrentDictionary _dicNullableValueProperty = new ConcurrentDictionary(); static ConcurrentDictionary _dicFreeSqlGlobalExtensionsAsSelectExpression = new ConcurrentDictionary(); - internal string ExpressionLambdaToSql(Expression exp, List _tables, List _selectColumnMap, Func 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(), getSelectGroupingMapString, SelectTableInfoType.LeftJoin, isQuoteName, true, ExpressionStyle.AsSelect); + var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List(), 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; - //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(); @@ -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 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlCallString(MethodCallExpression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style); - internal abstract string ExpressionLambdaToSqlOther(Expression exp, List _tables, List _selectColumnMap, Func 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 _tables { get; set; } + public List _selectColumnMap { get; set; } + public Func 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 v1, Func 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)); + } } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs index 4e1f81b0..af47d06b 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs @@ -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; } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index f410aa6a..68de86c1 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -66,7 +66,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract List ExecuteDeleted(); public abstract Task> ExecuteDeletedAsync(); - public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, exp?.Body, null)); + public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, exp?.Body, null)); public IDelete Where(string sql, object parms = null) { if (string.IsNullOrEmpty(sql)) return this; var args = new AopWhereEventArgs(sql, parms); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 9e9e3e01..65effd37 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -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; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index bfeca942..2086b899 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -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); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 4b9edbed..f02d8a9e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -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; } diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 6f013eab..b6c99276 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -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(); - 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 Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, expression?.Body, null)); + public IUpdate Where(Expression> expression) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, null, expression?.Body, null)); public IUpdate 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; } diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index f62d1772..6d4e8cdd 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -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() : 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 ("); diff --git a/FreeSql/Internal/Model/ColumnInfo.cs b/FreeSql/Internal/Model/ColumnInfo.cs index 6ec51ed4..24bfdcd9 100644 --- a/FreeSql/Internal/Model/ColumnInfo.cs +++ b/FreeSql/Internal/Model/ColumnInfo.cs @@ -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> _dicGetMapValue = new ConcurrentDictionary>(); + 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>( + 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(); + 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>(Expression.Block(new[] { retExp }, blockExp), new[] { paramExp }).Compile(); + }); + return func(obj); + } + static ConcurrentDictionary> _dicSetMapValue = new ConcurrentDictionary>(); + 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>( + 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>( + 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); + } } } \ No newline at end of file diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index 7b35a8ae..2f1c2aeb 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -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; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c83a49b0..3c63aecd 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -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()); //区分数据库类型缓存 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(); 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 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(); 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>( 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>> _dicGetDataReaderValue = new ConcurrentDictionary>>(); 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>(exp, parmExp).Compile(); }); return func(value); - #region oldcode - //var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary>()).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>(parmExp, parmExp).Compile(); - - // if (type.IsArray) { - // var elementType = type.GetElementType(); - // if (elementType == valueType.GetElementType()) return Expression.Lambda>(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>( - // 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>( - // 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>( - // Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(parmExp, typeof(string))), typeof(object)) - // , parmExp).Compile(); - // return Expression.Lambda>(parmExp, parmExp).Compile(); - - // case "MygisPoint": return Expression.Lambda>( - // Expression.TypeAs( - // Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), - // typeof(MygisPoint) - // ), parmExp).Compile(); - // case "MygisLineString": return Expression.Lambda>( - // Expression.TypeAs( - // Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), - // typeof(MygisLineString) - // ), parmExp).Compile(); - // case "MygisPolygon": return Expression.Lambda>( - // Expression.TypeAs( - // Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), - // typeof(MygisPolygon) - // ), parmExp).Compile(); - // case "MygisMultiPoint": return Expression.Lambda>( - // Expression.TypeAs( - // Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), - // typeof(MygisMultiPoint) - // ), parmExp).Compile(); - // case "MygisMultiLineString": return Expression.Lambda>( - // Expression.TypeAs( - // Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), - // typeof(MygisMultiLineString) - // ), parmExp).Compile(); - // case "MygisMultiPolygon": return Expression.Lambda>( - // Expression.TypeAs( - // Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), - // typeof(MygisMultiPolygon) - // ), parmExp).Compile(); - // case "Newtonsoft.Json.Linq.JToken": return Expression.Lambda>( - // 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>( - // 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>( - // 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>(parmExp, parmExp).Compile(); - // } - // if (type != valueType) { - // if (type.FullName == "System.TimeSpan") return Expression.Lambda>( - // Expression.Convert(Expression.Call( - // MethodTimeSpanFromSeconds, - // Expression.Call(MethodDoubleParse, Expression.Call(MethodToString, parmExp)) - // ), typeof(object)), parmExp).Compile(); - // return Expression.Lambda>( - // Expression.Call(MethodConvertChangeType, parmExp, Expression.Constant(type, typeof(Type))) - // , parmExp).Compile(); - // } - // return Expression.Lambda>(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); diff --git a/FreeSql/Internal/UtilsReflection.cs b/FreeSql/Internal/UtilsReflection.cs deleted file mode 100644 index 26d36a59..00000000 --- a/FreeSql/Internal/UtilsReflection.cs +++ /dev/null @@ -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 _cacheGetTableByEntity = new ConcurrentDictionary(); -// 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(string sql, object obj, string paramPrefix, Func 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(); -// 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 dicExecuteArrayRowReadClassOrTuple = new Dictionary { -// [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)] = true, -// [typeof(NpgsqlRange)] = true, -// [typeof(NpgsqlRange)] = true, -// [typeof(NpgsqlRange)] = 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)] = true, -// [typeof(JToken)] = true, -// [typeof(JObject)] = true, -// [typeof(JArray)] = true, -// }; - -// internal static ConcurrentDictionary _dicClassConstructor = new ConcurrentDictionary(); -// internal static ConcurrentDictionary _dicTupleConstructor = new ConcurrentDictionary(); -// 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 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)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); -// } -// } -//} \ No newline at end of file diff --git a/FreeSql/MySql/Curd/MySqlDelete.cs b/FreeSql/MySql/Curd/MySqlDelete.cs index f95d7b4a..02360394 100644 --- a/FreeSql/MySql/Curd/MySqlDelete.cs +++ b/FreeSql/MySql/Curd/MySqlDelete.cs @@ -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(_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(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray()); diff --git a/FreeSql/MySql/Curd/MySqlInsert.cs b/FreeSql/MySql/Curd/MySqlInsert.cs index f9d6a3f5..55d24548 100644 --- a/FreeSql/MySql/Curd/MySqlInsert.cs +++ b/FreeSql/MySql/Curd/MySqlInsert.cs @@ -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(_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(_connection, _transaction, CommandType.Text, sb.ToString(), _params); diff --git a/FreeSql/MySql/Curd/MySqlUpdate.cs b/FreeSql/MySql/Curd/MySqlUpdate.cs index bf33467f..789265e2 100644 --- a/FreeSql/MySql/Curd/MySqlUpdate.cs +++ b/FreeSql/MySql/Curd/MySqlUpdate.cs @@ -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(_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(_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(")"); diff --git a/FreeSql/MySql/MySqlAdo/MySqlAdo.cs b/FreeSql/MySql/MySqlAdo/MySqlAdo.cs index 6e3d964c..388aaeb0 100644 --- a/FreeSql/MySql/MySqlAdo/MySqlAdo.cs +++ b/FreeSql/MySql/MySqlAdo/MySqlAdo.cs @@ -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() { diff --git a/FreeSql/MySql/MySqlExpression.cs b/FreeSql/MySql/MySqlExpression.cs index 974c4b69..a8664080 100644 --- a/FreeSql/MySql/MySqlExpression.cs +++ b/FreeSql/MySql/MySqlExpression.cs @@ -12,8 +12,8 @@ namespace FreeSql.MySql { public MySqlExpression(CommonUtils common) : base(common) { } - internal override string ExpressionLambdaToSqlOther(Expression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); if (exp.Object == null) { switch (exp.Method.Name) { case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; diff --git a/FreeSql/MySql/MySqlUtils.cs b/FreeSql/MySql/MySqlUtils.cs index 028389e2..73015d03 100644 --- a/FreeSql/MySql/MySqlUtils.cs +++ b/FreeSql/MySql/MySqlUtils.cs @@ -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)})"; diff --git a/FreeSql/Oracle/Curd/OracleInsert.cs b/FreeSql/Oracle/Curd/OracleInsert.cs index 90a4b810..c484fb8d 100644 --- a/FreeSql/Oracle/Curd/OracleInsert.cs +++ b/FreeSql/Oracle/Curd/OracleInsert.cs @@ -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; diff --git a/FreeSql/Oracle/Curd/OracleUpdate.cs b/FreeSql/Oracle/Curd/OracleUpdate.cs index 6f1166f4..0529d122 100644 --- a/FreeSql/Oracle/Curd/OracleUpdate.cs +++ b/FreeSql/Oracle/Curd/OracleUpdate.cs @@ -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(")"); diff --git a/FreeSql/Oracle/OracleAdo/OracleAdo.cs b/FreeSql/Oracle/OracleAdo/OracleAdo.cs index 83ae6f6c..0991e36a 100644 --- a/FreeSql/Oracle/OracleAdo/OracleAdo.cs +++ b/FreeSql/Oracle/OracleAdo/OracleAdo.cs @@ -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("'", "''"), "'"); diff --git a/FreeSql/Oracle/OracleExpression.cs b/FreeSql/Oracle/OracleExpression.cs index 65f942f8..6dde4826 100644 --- a/FreeSql/Oracle/OracleExpression.cs +++ b/FreeSql/Oracle/OracleExpression.cs @@ -12,8 +12,8 @@ namespace FreeSql.Oracle { public OracleExpression(CommonUtils common) : base(common) { } - internal override string ExpressionLambdaToSqlOther(Expression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); if (exp.Object == null) { switch (exp.Method.Name) { //case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; diff --git a/FreeSql/Oracle/OracleUtils.cs b/FreeSql/Oracle/OracleUtils.cs index 752b29b1..4666a797 100644 --- a/FreeSql/Oracle/OracleUtils.cs +++ b/FreeSql/Oracle/OracleUtils.cs @@ -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)}"; diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs index 9a5c05d4..14ec2b3e 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs @@ -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(_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(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray()); diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs index 8931a62e..bb320199 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs @@ -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(_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(_connection, _transaction, CommandType.Text, sb.ToString(), _params); diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs index 415a56eb..7b2ca281 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -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(_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(_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(")"); diff --git a/FreeSql/PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/FreeSql/PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index 82166704..ed62824f 100644 --- a/FreeSql/PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/FreeSql/PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -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() { diff --git a/FreeSql/PostgreSQL/PostgreSQLExpression.cs b/FreeSql/PostgreSQL/PostgreSQLExpression.cs index f9682438..4e1f81ed 100644 --- a/FreeSql/PostgreSQL/PostgreSQLExpression.cs +++ b/FreeSql/PostgreSQL/PostgreSQLExpression.cs @@ -13,8 +13,8 @@ namespace FreeSql.PostgreSQL { public PostgreSQLExpression(CommonUtils common) : base(common) { } - internal override string ExpressionLambdaToSqlOther(Expression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { + Func 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'))"; diff --git a/FreeSql/PostgreSQL/PostgreSQLUtils.cs b/FreeSql/PostgreSQL/PostgreSQLUtils.cs index e76b25e4..3fd7c9a4 100644 --- a/FreeSql/PostgreSQL/PostgreSQLUtils.cs +++ b/FreeSql/PostgreSQL/PostgreSQLUtils.cs @@ -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)}"; diff --git a/FreeSql/SqlServer/Curd/SqlServerDelete.cs b/FreeSql/SqlServer/Curd/SqlServerDelete.cs index 365d7698..b4d55304 100644 --- a/FreeSql/SqlServer/Curd/SqlServerDelete.cs +++ b/FreeSql/SqlServer/Curd/SqlServerDelete.cs @@ -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; } diff --git a/FreeSql/SqlServer/Curd/SqlServerInsert.cs b/FreeSql/SqlServer/Curd/SqlServerInsert.cs index ded77b60..e778aaad 100644 --- a/FreeSql/SqlServer/Curd/SqlServerInsert.cs +++ b/FreeSql/SqlServer/Curd/SqlServerInsert.cs @@ -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; } diff --git a/FreeSql/SqlServer/Curd/SqlServerUpdate.cs b/FreeSql/SqlServer/Curd/SqlServerUpdate.cs index 382ab633..efebc39e 100644 --- a/FreeSql/SqlServer/Curd/SqlServerUpdate.cs +++ b/FreeSql/SqlServer/Curd/SqlServerUpdate.cs @@ -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; } } diff --git a/FreeSql/SqlServer/SqlServerAdo/SqlServerAdo.cs b/FreeSql/SqlServer/SqlServerAdo/SqlServerAdo.cs index 4675e7e5..e8703114 100644 --- a/FreeSql/SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/FreeSql/SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -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() { diff --git a/FreeSql/SqlServer/SqlServerExpression.cs b/FreeSql/SqlServer/SqlServerExpression.cs index 99366be1..83cfe810 100644 --- a/FreeSql/SqlServer/SqlServerExpression.cs +++ b/FreeSql/SqlServer/SqlServerExpression.cs @@ -12,8 +12,8 @@ namespace FreeSql.SqlServer { public SqlServerExpression(CommonUtils common) : base(common) { } - internal override string ExpressionLambdaToSqlOther(Expression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { + Func 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'))"; diff --git a/FreeSql/SqlServer/SqlServerUtils.cs b/FreeSql/SqlServer/SqlServerUtils.cs index c84e2071..74aef87e 100644 --- a/FreeSql/SqlServer/SqlServerUtils.cs +++ b/FreeSql/SqlServer/SqlServerUtils.cs @@ -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) { diff --git a/FreeSql/Sqlite/Curd/SqliteUpdate.cs b/FreeSql/Sqlite/Curd/SqliteUpdate.cs index 0f80fb62..39543f8f 100644 --- a/FreeSql/Sqlite/Curd/SqliteUpdate.cs +++ b/FreeSql/Sqlite/Curd/SqliteUpdate.cs @@ -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(")"); diff --git a/FreeSql/Sqlite/SqliteAdo/SqliteAdo.cs b/FreeSql/Sqlite/SqliteAdo/SqliteAdo.cs index a065a624..736002a4 100644 --- a/FreeSql/Sqlite/SqliteAdo/SqliteAdo.cs +++ b/FreeSql/Sqlite/SqliteAdo/SqliteAdo.cs @@ -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() { diff --git a/FreeSql/Sqlite/SqliteExpression.cs b/FreeSql/Sqlite/SqliteExpression.cs index 04aeb62e..97d2f80c 100644 --- a/FreeSql/Sqlite/SqliteExpression.cs +++ b/FreeSql/Sqlite/SqliteExpression.cs @@ -12,8 +12,8 @@ namespace FreeSql.Sqlite { public SqliteExpression(CommonUtils common) : base(common) { } - internal override string ExpressionLambdaToSqlOther(Expression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) { + Func 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 _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName, bool isDisableDiyParse, ExpressionStyle style) { - Func getExp = exparg => ExpressionLambdaToSql(exparg, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName, isDisableDiyParse, style); + internal override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); if (exp.Object == null) { switch (exp.Method.Name) { case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; diff --git a/FreeSql/Sqlite/SqliteUtils.cs b/FreeSql/Sqlite/SqliteUtils.cs index 98540fe1..5d7c13e8 100644 --- a/FreeSql/Sqlite/SqliteUtils.cs +++ b/FreeSql/Sqlite/SqliteUtils.cs @@ -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)}";