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
相关产品推荐
相关产品推荐

