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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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<EnumTestMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<EnumTestMap>().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<EnumTestMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().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<EnumTestMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<EnumTestMap>().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<EnumTestMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().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<EnumTestMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<EnumTestMap>().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<EnumTestMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().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<EnumTestMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<EnumTestMap>().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<EnumTestMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().SetSource(item).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First());
find = orm.Select<EnumTestMap>().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<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(0, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(1, orm.Delete<EnumTestMap>().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows());
Assert.Null(orm.Select<EnumTestMap>().Where(a => a.id == item.id).First());
}
}
}

View File

@ -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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows());
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows());
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows());
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows());
Assert.Equal(0, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows());
Assert.Equal(1, orm.Delete<ToStringMap>().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
var find = orm.Select<ToStringMap>().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<ToStringMap>().AppendData(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().SetSource(item).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows());
find = orm.Select<ToStringMap>().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<ToStringMap>().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows());
Assert.Null(orm.Select<ToStringMap>().Where(a => a.id == item.id).First());
}
}
}

View File

@ -71,7 +71,7 @@ namespace FreeSql.Tests.PostgreSQLExpression {
[Fact] [Fact]
public void Log() { public void Log() {
var data = new List<object>(); var data = new List<object>();
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] [Fact]
public void Log10() { public void Log10() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,7 @@ namespace FreeSql.Internal.CommonProvider {
string getSelectGroupingMapString(Expression[] members) { string getSelectGroupingMapString(Expression[] members) {
if (members.Any() == false) return _map.DbField; if (members.Any() == false) return _map.DbField;
var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name;
switch(parentName) { switch (parentName) {
case "Key": case "Key":
var read = _map; var read = _map;
for (var a = 0; a < members.Length; a++) { 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); var parmExp = Expression.Parameter(tb.Table.Type, tb.Alias);
Expression retExp = parmExp; Expression retExp = parmExp;
for (var a = foridx; a < members.Length; a++) { for (var a = foridx; a < members.Length; a++) {
switch(members[a].NodeType) { switch (members[a].NodeType) {
case ExpressionType.Call: case ExpressionType.Call:
retExp = Expression.Call(retExp, (members[a] as MethodCallExpression).Method); retExp = Expression.Call(retExp, (members[a] as MethodCallExpression).Method);
break; break;
@ -64,7 +64,7 @@ namespace FreeSql.Internal.CommonProvider {
return null; 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; return null;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray()); var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());
@ -38,7 +38,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray()); var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());

View File

@ -41,7 +41,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
return _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params); return _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);
@ -56,7 +56,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
return await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params); return await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);

View File

@ -30,7 +30,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -47,7 +47,7 @@ namespace FreeSql.MySql.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -57,14 +57,14 @@ namespace FreeSql.MySql.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) { 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; return;
} }
caseWhen.Append("CONCAT("); caseWhen.Append("CONCAT(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(", "); 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; ++pkidx;
} }
caseWhen.Append(")"); caseWhen.Append(")");
@ -72,14 +72,14 @@ namespace FreeSql.MySql.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) { 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; return;
} }
sb.Append("CONCAT("); sb.Append("CONCAT(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(", "); 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; ++pkidx;
} }
sb.Append(")"); sb.Append(")");

View File

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

View File

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

View File

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

View File

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

View File

@ -30,14 +30,14 @@ namespace FreeSql.Oracle.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) { 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; return;
} }
caseWhen.Append("("); caseWhen.Append("(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(" || "); 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; ++pkidx;
} }
caseWhen.Append(")"); caseWhen.Append(")");
@ -45,14 +45,14 @@ namespace FreeSql.Oracle.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) { 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; return;
} }
sb.Append("("); sb.Append("(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(" || "); 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; ++pkidx;
} }
sb.Append(")"); sb.Append(")");

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray()); var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());
@ -38,7 +38,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray()); var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.ToArray());

View File

@ -53,7 +53,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
return _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params); return _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);
@ -68,7 +68,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
return await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params); return await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params);

View File

@ -30,7 +30,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); var ret = _orm.Ado.Query<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -47,7 +47,7 @@ namespace FreeSql.PostgreSQL.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); var ret = await _orm.Ado.QueryAsync<T1>(_connection, _transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray());
@ -57,14 +57,14 @@ namespace FreeSql.PostgreSQL.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) { 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; return;
} }
caseWhen.Append("("); caseWhen.Append("(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(" || "); 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; ++pkidx;
} }
caseWhen.Append(")"); caseWhen.Append(")");
@ -72,14 +72,14 @@ namespace FreeSql.PostgreSQL.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) { 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; return;
} }
sb.Append("("); sb.Append("(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(" || "); 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; ++pkidx;
} }
sb.Append(")"); sb.Append(")");

View File

@ -26,9 +26,11 @@ namespace FreeSql.PostgreSQL {
} }
static DateTime dt1970 = new DateTime(1970, 1, 1); static DateTime dt1970 = new DateTime(1970, 1, 1);
public override object AddslashesProcessParam(object param) { public override object AddslashesProcessParam(object param, Type mapType) {
bool isdic = false;
if (param == null) return "NULL"; 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?) if (param is bool || param is bool?)
return (bool)param ? "'t'" : "'f'"; return (bool)param ? "'t'" : "'f'";
else if (param is string || param is char) else if (param is string || param is char)
@ -57,12 +59,10 @@ namespace FreeSql.PostgreSQL {
} else if (param is IEnumerable) { } else if (param is IEnumerable) {
var sb = new StringBuilder(); var sb = new StringBuilder();
var ie = param as IEnumerable; 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 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() { protected override DbCommand CreateCommand() {

View File

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

View File

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

View File

@ -21,7 +21,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
@ -43,7 +43,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }

View File

@ -44,7 +44,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
@ -64,7 +64,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }

View File

@ -30,7 +30,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
@ -52,7 +52,7 @@ namespace FreeSql.SqlServer.Curd {
var colidx = 0; var colidx = 0;
foreach (var col in _table.Columns.Values) { foreach (var col in _table.Columns.Values) {
if (colidx > 0) sb.Append(", "); 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; ++colidx;
} }
@ -68,14 +68,14 @@ namespace FreeSql.SqlServer.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) { 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; return;
} }
caseWhen.Append("("); caseWhen.Append("(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(", "); 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; ++pkidx;
} }
caseWhen.Append(")"); caseWhen.Append(")");
@ -83,13 +83,13 @@ namespace FreeSql.SqlServer.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) { 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; return;
} }
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(", "); 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; ++pkidx;
} }
} }

View File

@ -23,8 +23,10 @@ namespace FreeSql.SqlServer {
} }
} }
static DateTime dt1970 = new DateTime(1970, 1, 1); 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 (param == null) return "NULL";
if (mapType != null && mapType != param.GetType())
param = Utils.GetDataReaderValue(mapType, param);
if (param is bool || param is bool?) if (param is bool || param is bool?)
return (bool)param ? 1 : 0; return (bool)param ? 1 : 0;
else if (param is string || param is char) else if (param is string || param is char)
@ -39,18 +41,16 @@ namespace FreeSql.SqlServer {
} else if (param is DateTimeOffset || param is DateTimeOffset?) { } else if (param is DateTimeOffset || param is DateTimeOffset?) {
if (param.Equals(DateTimeOffset.MinValue) == true) param = new DateTimeOffset(new DateTime(1970, 1, 1), TimeSpan.Zero); 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"), "'"); 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; return ((TimeSpan)param).TotalSeconds;
else if (param is IEnumerable) { else if (param is IEnumerable) {
var sb = new StringBuilder(); var sb = new StringBuilder();
var ie = param as IEnumerable; 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 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() { protected override DbCommand CreateCommand() {

View File

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

View File

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

View File

@ -30,14 +30,14 @@ namespace FreeSql.Sqlite.Curd {
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) {
if (_table.Primarys.Length == 1) { 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; return;
} }
caseWhen.Append("CONCAT("); caseWhen.Append("CONCAT(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) caseWhen.Append(", "); 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; ++pkidx;
} }
caseWhen.Append(")"); caseWhen.Append(")");
@ -45,14 +45,14 @@ namespace FreeSql.Sqlite.Curd {
protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) {
if (_table.Primarys.Length == 1) { 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; return;
} }
sb.Append("CONCAT("); sb.Append("CONCAT(");
var pkidx = 0; var pkidx = 0;
foreach (var pk in _table.Primarys) { foreach (var pk in _table.Primarys) {
if (pkidx > 0) sb.Append(", "); 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; ++pkidx;
} }
sb.Append(")"); sb.Append(")");

View File

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

View File

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

View File

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