You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ServiceStack.OrmLite查询PostgreSQL动态SQL列名大小写不符如何解决?

问题描述

我通过代码生成了如下动态SQL查询语句:

SELECT
 "public"."member_contact"."member_id" AS MemberId
 ,  "public"."member_contact"."contact_id" AS ContactId
 ,  "public"."member_contact"."modified_by" AS ModifiedBy
 ,  "public"."member_contact"."lm_prog" AS LmProg
 ,  "public"."member_contact"."created_by" AS CreatedBy
 ,  "public"."member_contact"."cr_prog" AS CrProg
 ,  "public"."member_contact"."id" AS Id
 ,  "public"."member_contact"."modified_date" AS ModifiedDate
 ,  "public"."member_contact"."created_date" AS CreatedDate
FROM "public"."member_contact"

随后通过ServiceStack服务处理方法执行该查询:

var records = await Db.QueryAsync(sqlStatements.SelectStatement, p);

该方法返回IEnumerable<dynamic>类型结果,但返回的records中属性名称全部为小写(例如memberid而非MemberId等),如何让IEnumerable<dynamic>返回的属性名称与SQL语句中定义的列别名一致?

解决方案

方法1:全局配置OrmLite保留列名大小写

ServiceStack OrmLite默认会将查询结果的列名转为小写,你可以通过修改PostgreSQL方言的配置来保留原始列别名的大小写格式:

// 在数据库连接初始化时添加配置
PostgreSqlDialect.Provider.StringComparison = StringComparison.Ordinal;
PostgreSqlDialect.Provider.UseQuotedColumns = true;

配置生效后,QueryAsync返回的dynamic对象会严格匹配SQL中定义的MemberId、ContactId等列别名。

方法2:使用强类型DTO接收结果

定义一个与SQL列别名完全匹配的DTO类:

public class MemberContactDto
{
    public int MemberId { get; set; }
    public int ContactId { get; set; }
    public string ModifiedBy { get; set; }
    public string LmProg { get; set; }
    public string CreatedBy { get; set; }
    public string CrProg { get; set; }
    public int Id { get; set; }
    public DateTime ModifiedDate { get; set; }
    public DateTime CreatedDate { get; set; }
}

然后用强类型方式执行查询:

var records = await Db.QueryAsync<MemberContactDto>(sqlStatements.SelectStatement, p);

OrmLite会自动将列别名映射到DTO的属性,不受默认大小写转换影响,同时还能获得类型安全的好处。

方法3:手动转换dynamic属性名(临时场景)

如果不想修改全局配置或使用DTO,可以在查询后手动重命名属性:

var dynamicRecords = await Db.QueryAsync(sqlStatements.SelectStatement, p);
var fixedRecords = dynamicRecords.Select(x => 
{
    var expando = new ExpandoObject() as IDictionary<string, object>;
    foreach (var prop in x.GetType().GetProperties())
    {
        // 按实际列别名映射小写属性名
        var targetName = prop.Name switch
        {
            "memberid" => "MemberId",
            "contactid" => "ContactId",
            "modifiedby" => "ModifiedBy",
            "lmprog" => "LmProg",
            "createdby" => "CreatedBy",
            "crprog" => "CrProg",
            "modifieddate" => "ModifiedDate",
            "createddate" => "CreatedDate",
            _ => prop.Name
        };
        expando[targetName] = prop.GetValue(x);
    }
    return expando;
});

这种方法适合临时需求,但属性较多时会比较繁琐。

内容的提问来源于stack exchange,提问作者Shawn de Wet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:38:25