gpt4 book ai didi

entity-framework - 使用 EF Core 3.1 将 SQL 查询挂载到 EXTRACT postgresql 函数

转载 作者:行者123 更新时间:2023-12-04 15:16:29 27 4
gpt4 key购买 nike

我在我的 ASP.NET 项目中使用 Postgresql 和 EF Core 3.1

我想生成这样的 sql 片段:

EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE f."MyDateTimeField")"

因此,我在 DbContext 的 OnModelCreating 方法上编写了这段代码:

    modelBuilder
.HasDbFunction(typeof(MyDbFunctions).GetMethod(
nameof(MyDbFunctions.ExtractEpochFromTimestampWithTimezone)))
.HasTranslation(args
=> SqlFunctionExpression.Create(
"EXTRACT",
new []
{
new SqlFragmentExpression(
$"EPOCH FROM TIMESTAMP WITH TIME ZONE"),
args.First()
}, typeof(double), null));

但是生成的 SQL 片段是:

EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE, f."MyDateTimeField")

请注意,SQL 在单词“ZONE”之后有一个“,”。

如何修复我的代码以生成没有这个“,”的 SQL 片段?

最佳答案

任何面临与上述相同问题的人。我已经用下面的代码解决了上面的问题

测试实体

public class Employee
{
public int Id { get; set; }
public DateTime DOB { get; set; }
public string Name { get; set; }

}

带有自定义 postgres EXTRACT 函数的 EF Core Dbcontext

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDbFunction(ExtractMethod)
.HasTranslation(args =>
{
var arguments = args.ToList();
//{((Microsoft.EntityFrameworkCore.Query.SqlExpressions.ColumnExpression)arguments[1]).TypeMapping.StoreType}
arguments[0] = new SqlFragmentExpression($"{((Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlConstantExpression)arguments[0]).Value} from {((Microsoft.EntityFrameworkCore.Query.SqlExpressions.ColumnExpression)arguments[1]).Table.Alias}.\"{((Microsoft.EntityFrameworkCore.Query.SqlExpressions.ColumnExpression)arguments[1]).Name}\"");
arguments.RemoveAt(1);
return new SqlFunctionExpression("EXTRACT",
arguments,
false,
new bool[] { false, false},
typeof(decimal),
RelationalTypeMapping.NullMapping);
});
}

被映射的EF函数

private readonly MethodInfo ExtractMethod
= typeof(Context).GetRuntimeMethod(nameof(Extract), new[] { typeof(string), typeof(DateTime) });
public DateTime Extract(string field, DateTime source)
=> throw new NotSupportedException();

更新代码

上述方法在使用嵌套函数时会失败。我已经通过适当的实现对其进行了更新。我希望这会帮助其他人

添加了一个名为 ExtractExpression 的新类

 public class ExtractExpression:SqlFunctionExpression
{
private readonly IReadOnlyCollection<SqlExpression> _params;

public ExtractExpression(IReadOnlyCollection<SqlExpression> parameters):base("EXTRACT", true, typeof(double), RelationalTypeMapping.NullMapping)
{
_params = parameters;
}
protected override Expression Accept(ExpressionVisitor visitor)
{
if (!(visitor is QuerySqlGenerator))
return base.Accept(visitor);

visitor.Visit(new SqlFragmentExpression("EXTRACT(")); //Postgres function name
visitor.Visit(_params.First()); //First paramenter
visitor.Visit(new SqlFragmentExpression(" from ")); //query clause
visitor.Visit(_params.Skip(1).First()); //2nd parameter
visitor.Visit(new SqlFragmentExpression(")")); //function ending brace

return this;
}
protected override void Print([NotNullAttribute] ExpressionPrinter expressionPrinter)
{
Console.WriteLine(expressionPrinter);
}
}

OnModeCreating 函数中添加以下代码

 modelBuilder.HasDbFunction(ExtractMethod)
.HasTranslation(expressions =>
{
return new ExtractExpression(expressions);
});

关于entity-framework - 使用 EF Core 3.1 将 SQL 查询挂载到 EXTRACT postgresql 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64244947/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com