Skip to content

Commit

Permalink
fix:修复使用DateTime相减时,出现IIF无法转换表达式的错误
Browse files Browse the repository at this point in the history
  • Loading branch information
xieyidong committed Dec 12, 2024
1 parent 206762e commit 01967e7
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
66 changes: 66 additions & 0 deletions FreeSql.Tests/FreeSql.Tests/Internal/CommonExpressionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FreeSql.DataAnnotations;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore.Metadata;
using Xunit;

namespace FreeSql.Tests.Internal
Expand Down Expand Up @@ -250,6 +252,7 @@ public void IIFTest01()
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value ? 10 : 11);
Assert.Equal(@"SELECT case when a.""BoolNullable"" = 1 AND a.""Id"" > 0 AND a.""BoolNullable"" = 1 then 10 else 11 end as1
FROM ""IIFTest01Model"" a", sql);

}

class IIFTest01Model
Expand All @@ -258,5 +261,68 @@ class IIFTest01Model
public bool Bool { get; set; }
public bool? BoolNullable { get; set; }
}

[Fact]
public void IIFTest02()
{
var parameters = new List<DbParameter>();

var fsql = g.sqlite;
var sql = "";
var startTime = DateTime.UtcNow;
var query = fsql.Select<IIFTest02Model1, IIFTest02Model2>()
.WithParameters(parameters)
.InnerJoin((model1, model2) =>
model2.StartDateTime == startTime
&& model1.StartTime <= model2.EndDateTime
&& model1.StopTime > model2.StartDateTime)
.GroupBy((model1, model2) => new
{
model1.EntityId,
model2.StartDateTime,
model2.EndDateTime,
})
.WithTempQuery(group => new
{
EntityId = group.Key.EntityId,
DateTime = group.Key.StartDateTime,
TotalRunTime = group.Sum<double>(((group.Value.Item1.StopTime > group.Key.EndDateTime ? group.Key.EndDateTime : group.Value.Item1.StopTime)
- (group.Value.Item1.StartTime < group.Key.StartDateTime ? group.Key.StartDateTime : group.Value.Item1.StartTime)).TotalSeconds),
Count = group.Count()
})
.WithParameters(parameters);

sql = query.ToSql();
Assert.Equal($@"SELECT *
FROM (
SELECT a.""EntityId"", b.""StartDateTime"" ""DateTime"", sum(((strftime('%s',case when a.""StopTime"" > b.""EndDateTime"" then b.""EndDateTime"" else a.""StopTime"" end)-strftime('%s',case when a.""StartTime"" < b.""StartDateTime"" then b.""StartDateTime"" else a.""StartTime"" end)))) ""TotalRunTime"", count(1) ""Count""
FROM ""IIFTest02Model1"" a
INNER JOIN ""IIFTest02Model2"" b ON b.""StartDateTime"" = '{startTime.ToString("yyyy-MM-dd HH:mm:ss")}' AND a.""StartTime"" <= b.""EndDateTime"" AND a.""StopTime"" > b.""StartDateTime""
GROUP BY a.""EntityId"", b.""StartDateTime"", b.""EndDateTime"" ) a", sql);

}
public class IIFTest02Model1
{
public long _Id { get; set; }
public long Id { get; set; }


public long EntityId { get; set; }

public DateTime StartTime { get; set; }
public DateTime StopTime { get; set; }

}

/// <summary>
/// 任务统计日期
/// </summary>
public class IIFTest02Model2
{
public long Id { get; set; }
public DateTime StartDateTime { get; set; }
public DateTime EndDateTime { get; set; }

}
}
}
8 changes: 7 additions & 1 deletion FreeSql/Internal/CommonExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1860,11 +1860,17 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
case "System.String": extRet = ExpressionLambdaToSqlMemberAccessString(exp4, tsc); break;
case "System.DateTime": extRet = ExpressionLambdaToSqlMemberAccessDateTime(exp4, tsc); break;
case "System.TimeSpan":
if (exp4.Expression != null && exp4.Expression.NodeType == ExpressionType.Call &&
if (exp4.Expression != null && (
// 如果是以 TimeSpan.Subtract(DateTime) 的方式调用的
(exp4.Expression.NodeType == ExpressionType.Call &&
exp4.Expression is MethodCallExpression exp4CallExp &&
exp4CallExp.Method.Name == "Subtract" &&
exp4CallExp.Object != null && exp4CallExp.Object.Type == typeof(DateTime) &&
exp4CallExp.Arguments.Count == 1 && exp4CallExp.Arguments[0].Type == typeof(DateTime))
// 如果是以 TimeSpan1 -/+ TimeSpan2 的方式调用的
|| (exp4.Expression.NodeType == ExpressionType.Subtract || exp4.Expression.NodeType == ExpressionType.Add)
)
)
{
var left = ExpressionLambdaToSql(exp4.Expression, tsc);
switch (exp4.Member.Name)
Expand Down

0 comments on commit 01967e7

Please sign in to comment.