Servicestack自动查询自定义约定不适用于PostgreSQL

时间:2018-04-25 20:40:16

标签: servicestack servicestack-autoquery autoquery-servicestack

我已经定义了新的隐式约定

autoQuery.ImplicitConventions.Add("%WithinLastDays", "{Field} > NOW() - INTERVAL '{Value} days'");

问题是对于postgres连接,查询被错误地翻译成

WHERE "TABLE"."FIELD" > NOW() - INTERVAL ':0 days'

并且它不会将参数发送到数据库。如果是内置约定,它可以正常工作。

更新

我试图定义EndsWithConvention,但是存在同样的问题 - 参数未传递给pgsql引擎(但它在SqlExpression中可用)

    autoQuery.EndsWithConventions
.Add("WithinLastDays", new QueryDbFieldAttribute() { Template= "{Field} >=  CURRENT_DATE - {Value}", ValueFormat= "interval '{0} days ago'" });

    autoQuery.EndsWithConventions
.Add("WithinLastDays", new QueryDbFieldAttribute() { Template= "{Field} >=  CURRENT_DATE - interval '{Value}'", ValueFormat= "{0} days ago" });

更新2 以下定义导致PostgresException:42601:błądskładniwlub blisko“$ 1”(对不起波兰语中的错误)

autoQuery.EndsWithConventions.Add("WithinLastDays", new QueryDbFieldAttribute() { Template= "{Field} >=  CURRENT_DATE - interval {Value}", ValueFormat= "{0} days ago" });

生成的查询是

  SELECT here columns
        FROM table
        WHERE table."publication_date" >=  CURRENT_DATE - interval $1
        LIMIT 100

更新3

autoQuery.EndsWithConventions.Add("WithinLastDays", new QueryDbFieldAttribute() { Template= "{Field} >=  CURRENT_DATE - {Value}", ValueFormat= "interval {0} 'days ago'" });

产生

SELECT ...
    FROM ...
    WHERE ...."publication_date" >=  CURRENT_DATE - $1

并发出PostgresException:42883:operator不存在:date - text

这是dto定义

[Route("/search/tenders")]
    public class FindTenders : QueryDb<TenderSearchResult>
    {
        public int? PublicationDateWithinLastDays { get; set; }
    }

模型:

public class EntitiySearchResult
{
    public DateTime PublicationDate { get; set; }
}

最终解决方案 @mythz解决了注册问题,并在原始查询中使用了interval子句。以下定义适用于从现在起过去X天内获取记录。谢谢@mythz

  var autoQuery = new AutoQueryFeature() { MaxLimit = 100 };
            autoQuery.EndsWithConventions.Add("WithinLastDays", new QueryDbFieldAttribute
            {
                Template = "{Field} >= CURRENT_DATE + {Value}::interval",
                ValueFormat = "{0} days ago"
            });

1 个答案:

答案 0 :(得分:2)

如果要更改db need to use ValueFormat数据库参数的值,{Value}将替换为db参数,例如ValueFormat="{0} days"

要将ValueFormat格式定义为register an EndsWithConventions所需的隐式约定,例如:

autoQuery.EndsWithConventions.Add("WithinLastDays", new QueryDbFieldAttribute { 
    Template= "{Field} >= CURRENT_DATE + {Value}::interval", 
    ValueFormat= "{0} days ago" 
});

另请注意,您可能希望CURRENT_DATE + interval不是-