mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 修复 pgsql Geo 函数自定义解析深度问题;#1422
This commit is contained in:
parent
ea7dae2fe8
commit
b164a08747
@ -590,7 +590,7 @@ namespace base_entity
|
|||||||
//.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper)
|
//.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper)
|
||||||
|
|
||||||
//.UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")
|
//.UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789")
|
||||||
.UseConnectionString(DataType.QuestDb, "host=localhost;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;")
|
//.UseConnectionString(DataType.QuestDb, "host=localhost;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;")
|
||||||
.UseMonitorCommand(cmd =>
|
.UseMonitorCommand(cmd =>
|
||||||
{
|
{
|
||||||
Console.WriteLine(cmd.CommandText + "\r\n");
|
Console.WriteLine(cmd.CommandText + "\r\n");
|
||||||
@ -602,6 +602,73 @@ namespace base_entity
|
|||||||
BaseEntity.Initialization(fsql, () => _asyncUow.Value);
|
BaseEntity.Initialization(fsql, () => _asyncUow.Value);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
fsql.Aop.ParseExpression += (_, e) =>
|
||||||
|
{
|
||||||
|
if (fsql.Ado.DataType == DataType.PostgreSQL)
|
||||||
|
{
|
||||||
|
if (e.Expression is MethodCallExpression callExp &&
|
||||||
|
callExp.Object is not null && typeof(Geometry).IsAssignableFrom(callExp.Method.DeclaringType))
|
||||||
|
{
|
||||||
|
var instance = callExp.Object;
|
||||||
|
var arguments = callExp.Arguments;
|
||||||
|
var Function = new Func<string, Expression[], Type, string>((dbfunc, args, returnType) =>
|
||||||
|
{
|
||||||
|
var inputArgs = string.Join(", ", args.Select(a =>
|
||||||
|
{
|
||||||
|
//var testParse = fsql.Aop.ParseExpressionHandler(fsql, new FreeSql.Aop.ParseExpressionEventArgs(a, e.FreeParse, e.Tables));
|
||||||
|
return e.FreeParse(a);
|
||||||
|
}));
|
||||||
|
return $"{dbfunc}({inputArgs})";
|
||||||
|
});
|
||||||
|
e.Result = callExp.Method.Name switch
|
||||||
|
{
|
||||||
|
nameof(Geometry.AsBinary) => Function("ST_AsBinary", new[] { instance }, typeof(byte[])),
|
||||||
|
nameof(Geometry.AsText) => Function("ST_AsText", new[] { instance }, typeof(string)),
|
||||||
|
nameof(Geometry.Buffer) => Function("ST_Buffer", new[] { instance }.Concat(arguments).ToArray(), typeof(Geometry)),
|
||||||
|
nameof(Geometry.Contains) => Function("ST_Contains", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.ConvexHull) => Function("ST_ConvexHull", new[] { instance }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.CoveredBy) => Function("ST_CoveredBy", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.Covers) => Function("ST_Covers", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.Crosses) => Function("ST_Crosses", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.Disjoint) => Function("ST_Disjoint", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.Difference) => Function("ST_Difference", new[] { instance, arguments[0] }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.Distance) => Function("ST_Distance", new[] { instance }.Concat(arguments).ToArray(), typeof(double)),
|
||||||
|
nameof(Geometry.EqualsExact) => Function("ST_OrderingEquals", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.EqualsTopologically) => Function("ST_Equals", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.GetGeometryN) => Function("ST_GeometryN", new[] { instance, arguments[0] }, typeof(Geometry)),
|
||||||
|
nameof(Polygon.GetInteriorRingN) => Function("ST_InteriorRingN", new[] { instance, arguments[0] }, typeof(Geometry)),
|
||||||
|
nameof(LineString.GetPointN) => Function("ST_PointN", new[] { instance, arguments[0] }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.Intersection) => Function("ST_Intersection", new[] { instance, arguments[0] }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.Intersects) => Function("ST_Intersects", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.IsWithinDistance) => Function("ST_DWithin", new[] { instance }.Concat(arguments).ToArray(), typeof(bool)),
|
||||||
|
nameof(Geometry.Normalized) => Function("ST_Normalize", new[] { instance }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.Overlaps) => Function("ST_Overlaps", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.Relate) => Function("ST_Relate", new[] { instance, arguments[0], arguments[1] }, typeof(bool)),
|
||||||
|
nameof(Geometry.Reverse) => Function("ST_Reverse", new[] { instance }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.SymmetricDifference) => Function("ST_SymDifference", new[] { instance, arguments[0] }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.ToBinary) => Function("ST_AsBinary", new[] { instance }, typeof(byte[])),
|
||||||
|
nameof(Geometry.ToText) => Function("ST_AsText", new[] { instance }, typeof(string)),
|
||||||
|
nameof(Geometry.Touches) => Function("ST_Touches", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
nameof(Geometry.Within) => Function("ST_Within", new[] { instance, arguments[0] }, typeof(bool)),
|
||||||
|
|
||||||
|
nameof(Geometry.Union) when arguments.Count == 0 => Function("ST_UnaryUnion", new[] { instance }, typeof(Geometry)),
|
||||||
|
nameof(Geometry.Union) when arguments.Count == 1 => Function("ST_Union", new[] { instance, arguments[0] }, typeof(Geometry)),
|
||||||
|
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (fsql.Ado.DataType == DataType.PostgreSQL)
|
||||||
|
{
|
||||||
|
Npgsql.NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite();
|
||||||
|
var geo = new Point(10, 20);
|
||||||
|
var xxx = fsql.Select<City>()
|
||||||
|
.Where(a => geo.GetGeometryN(0).Distance(a.Center) < 100).ToSql();
|
||||||
|
}
|
||||||
|
|
||||||
var qr1 = fsql.SelectLongSequence(10, () => new
|
var qr1 = fsql.SelectLongSequence(10, () => new
|
||||||
{
|
{
|
||||||
rndstr = QuestFunc.rnd_str(10, 5, 10, 0),
|
rndstr = QuestFunc.rnd_str(10, 5, 10, 0),
|
||||||
@ -1006,71 +1073,6 @@ var sql11111 = fsql.Select<Class1111>()
|
|||||||
.ToSql();
|
.ToSql();
|
||||||
|
|
||||||
|
|
||||||
fsql.Aop.ParseExpression += (_, e) =>
|
|
||||||
{
|
|
||||||
if (fsql.Ado.DataType == DataType.PostgreSQL)
|
|
||||||
{
|
|
||||||
if (e.Expression is MethodCallExpression callExp &&
|
|
||||||
callExp.Object is not null && typeof(Geometry).IsAssignableFrom(callExp.Method.DeclaringType))
|
|
||||||
{
|
|
||||||
var instance = callExp.Object;
|
|
||||||
var arguments = callExp.Arguments;
|
|
||||||
var Function = new Func<string, Expression[], Type, string>((dbfunc, args, returnType) =>
|
|
||||||
{
|
|
||||||
var inputArgs = string.Join(", ", args.Select(a =>
|
|
||||||
{
|
|
||||||
//var testParse = fsql.Aop.ParseExpressionHandler(fsql, new FreeSql.Aop.ParseExpressionEventArgs(a, e.FreeParse, e.Tables));
|
|
||||||
return e.FreeParse(a);
|
|
||||||
}));
|
|
||||||
return $"{dbfunc}({inputArgs})";
|
|
||||||
});
|
|
||||||
e.Result = callExp.Method.Name switch
|
|
||||||
{
|
|
||||||
nameof(Geometry.AsBinary) => Function("ST_AsBinary", new[] { instance }, typeof(byte[])),
|
|
||||||
nameof(Geometry.AsText) => Function("ST_AsText", new[] { instance }, typeof(string)),
|
|
||||||
nameof(Geometry.Buffer) => Function("ST_Buffer", new[] { instance }.Concat(arguments).ToArray(), typeof(Geometry)),
|
|
||||||
nameof(Geometry.Contains) => Function("ST_Contains", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.ConvexHull) => Function("ST_ConvexHull", new[] { instance }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.CoveredBy) => Function("ST_CoveredBy", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.Covers) => Function("ST_Covers", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.Crosses) => Function("ST_Crosses", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.Disjoint) => Function("ST_Disjoint", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.Difference) => Function("ST_Difference", new[] { instance, arguments[0] }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.Distance) => Function("ST_Distance", new[] { instance }.Concat(arguments).ToArray(), typeof(double)),
|
|
||||||
nameof(Geometry.EqualsExact) => Function("ST_OrderingEquals", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.EqualsTopologically) => Function("ST_Equals", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.GetGeometryN) => Function("ST_GeometryN", new[] { instance, arguments[0] }, typeof(Geometry)),
|
|
||||||
nameof(Polygon.GetInteriorRingN) => Function("ST_InteriorRingN", new[] { instance, arguments[0] }, typeof(Geometry)),
|
|
||||||
nameof(LineString.GetPointN) => Function("ST_PointN", new[] { instance, arguments[0] }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.Intersection) => Function("ST_Intersection", new[] { instance, arguments[0] }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.Intersects) => Function("ST_Intersects", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.IsWithinDistance) => Function("ST_DWithin", new[] { instance }.Concat(arguments).ToArray(), typeof(bool)),
|
|
||||||
nameof(Geometry.Normalized) => Function("ST_Normalize", new[] { instance }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.Overlaps) => Function("ST_Overlaps", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.Relate) => Function("ST_Relate", new[] { instance, arguments[0], arguments[1] }, typeof(bool)),
|
|
||||||
nameof(Geometry.Reverse) => Function("ST_Reverse", new[] { instance }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.SymmetricDifference) => Function("ST_SymDifference", new[] { instance, arguments[0] }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.ToBinary) => Function("ST_AsBinary", new[] { instance }, typeof(byte[])),
|
|
||||||
nameof(Geometry.ToText) => Function("ST_AsText", new[] { instance }, typeof(string)),
|
|
||||||
nameof(Geometry.Touches) => Function("ST_Touches", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
nameof(Geometry.Within) => Function("ST_Within", new[] { instance, arguments[0] }, typeof(bool)),
|
|
||||||
|
|
||||||
nameof(Geometry.Union) when arguments.Count == 0 => Function("ST_UnaryUnion", new[] { instance }, typeof(Geometry)),
|
|
||||||
nameof(Geometry.Union) when arguments.Count == 1 => Function("ST_Union", new[] { instance, arguments[0] }, typeof(Geometry)),
|
|
||||||
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (fsql.Ado.DataType == DataType.PostgreSQL)
|
|
||||||
{
|
|
||||||
Npgsql.NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite();
|
|
||||||
var geo = new Point(10, 20);
|
|
||||||
fsql.Select<City>()
|
|
||||||
.Where(a => geo.Distance(a.Center) < 100).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
var items = new List<User1>();
|
var items = new List<User1>();
|
||||||
for (var a = 0; a < 3; a++) items.Add(new User1 { Id = Guid.NewGuid(), Avatar = $"avatar{a}" });
|
for (var a = 0; a < 3; a++) items.Add(new User1 { Id = Guid.NewGuid(), Avatar = $"avatar{a}" });
|
||||||
|
@ -937,9 +937,12 @@ namespace FreeSql.Internal
|
|||||||
{
|
{
|
||||||
if (exp == null) return "";
|
if (exp == null) return "";
|
||||||
if (tsc.dbParams != null && tsc.mapColumnTmp != null && tsc.mapColumnTmp.CsType.NullableTypeOrThis() != exp.Type) tsc.SetMapColumnTmp(null);
|
if (tsc.dbParams != null && tsc.mapColumnTmp != null && tsc.mapColumnTmp.CsType.NullableTypeOrThis() != exp.Type) tsc.SetMapColumnTmp(null);
|
||||||
if (tsc.isDisableDiyParse == false)
|
if (tsc.isDisableDiyParse == false && tsc.parseDepth < 20)
|
||||||
{
|
{
|
||||||
var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, tsc.CloneDisableDiyParse()), tsc._tables);
|
var aopTsc = tsc.CloneDisableDiyParse();
|
||||||
|
aopTsc.parseDepth = tsc.parseDepth + 1;
|
||||||
|
aopTsc.isDisableDiyParse = false; //用深度控制
|
||||||
|
var args = new Aop.ParseExpressionEventArgs(exp, ukexp => ExpressionLambdaToSql(ukexp, aopTsc), tsc._tables);
|
||||||
if (_common._orm.Aop.ParseExpressionHandler != null)
|
if (_common._orm.Aop.ParseExpressionHandler != null)
|
||||||
{
|
{
|
||||||
_common._orm.Aop.ParseExpressionHandler(this, args);
|
_common._orm.Aop.ParseExpressionHandler(this, args);
|
||||||
@ -2276,6 +2279,7 @@ namespace FreeSql.Internal
|
|||||||
public List<GlobalFilter.Item> whereGlobalFilter { get; set; }
|
public List<GlobalFilter.Item> whereGlobalFilter { get; set; }
|
||||||
public List<DbParameter> dbParams { get; set; }
|
public List<DbParameter> dbParams { get; set; }
|
||||||
public string alias001 { get; set; } //单表字段的表别名
|
public string alias001 { get; set; } //单表字段的表别名
|
||||||
|
public int parseDepth { get; set; } //Aop 解析深度,防止死循环
|
||||||
|
|
||||||
public ExpTSC SetMapColumnTmp(ColumnInfo col)
|
public ExpTSC SetMapColumnTmp(ColumnInfo col)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user