如何让 Dapper 动态不区分大小写?
Posted
技术标签:
【中文标题】如何让 Dapper 动态不区分大小写?【英文标题】:How to get Dapper dynamic as case insensitive? 【发布时间】:2016-06-24 04:00:41 【问题描述】:我将 Dapper 与 Oracle 一起使用。 Oracle 查询结果列不区分大小写(除非你用双引号括起来),并且 Oracle 以大写形式返回列名。所以当使用动态时,Dapper 需要使用大写的字段名。
有没有办法让 Dapper 在使用 Dynamic 时不关心大小写?我在 DapperTable http://dapper-dot-net/Dapper/SqlMapper.DataTable.cs 中看到它使用带有 StringComparer.Ordinal 而不是 StringComparer.OrdinalIgnoreCase 的字典,我看不到任何更改它的选项。但我希望有人对此有解决方案,或者可以告诉我如何以更好的方式做到这一点。
例子:
var r = cnn.Query("select 'apple' fruit from dual").FirstOrDefault();
var f = r.Fruit; // f is set to null, but I want it to be "apple"
var F = r.FRUIT; // F is set to "apple", but I don't want to reference using all caps.
【问题讨论】:
我需要为此添加一个设置;问题是其他 ado.net 提供商得到了“正确”,并允许仅按大小写区分名称 @MarcGravell - 我看到了 Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;会使它不区分大小写,但如果是这样,我认为这仅用于属性匹配。如果可以选择使用 Dapper 开箱即用地完成这项工作,将会非常有帮助。 【参考方案1】:编辑:
请参阅this answer 以了解枚举属性以执行类似于我在下面的操作的替代方法(您可以将dynamic
转换为IDictionary<string,object>
)。
另外(对 Oracle 不够熟悉,不知道这是否属实)但也许如果您在 SELECT 查询中为列名起别名(即在 T-SQL 中使用 AS
)会覆盖大小写?
原文:
(Marc Gravell 说以下内容不适用于 Dapper。)
改编 this answer 的想法是否有效(特别是未经 Dapper 测试)?
using NUnit.Framework;
using System;
using System.Collections.Generic;
namespace ***Sandbox
public class ToDictionaryTests
[Test]
public void ItShouldWork()
// Arrange
var dapperResult = new
UPPER = 1,
lower = 2
;
// Act
var dictionary = dapperResult.ConvertToDictionary();
// Assert
Assert.That(dictionary["Upper"], Is.EqualTo(1));
Assert.That(dictionary["Lower"], Is.EqualTo(2));
public static class ObjectExtensions
private static readonly StringComparer ToDictionaryDefaultComparer =
StringComparer.OrdinalIgnoreCase;
/// <summary>
/// Converts an object's properties that can be read
/// to an IDictionary.
/// </summary>
public static IDictionary<string, object> ConvertToDictionary(
this object @this,
StringComparer comparer = null)
// The following is adapted from:
// https://***.com/a/15698713/569302
var dictionary = new Dictionary<string, object>(
comparer ?? ToDictionaryDefaultComparer);
foreach(var propertyInfo in @this.GetType().GetProperties())
if (propertyInfo.CanRead &&
propertyInfo.GetIndexParameters().Length == 0)
dictionary[propertyInfo.Name] =
propertyInfo.GetValue(@this, null);
return dictionary;
【讨论】:
那不行; Query 中的对象是真正意义上的dynamic
- 要求反射属性是没有意义的
嗨,像 Jared 这样的词,要使用 Oracle 区分大小写,您需要:从 dual 中选择 1 作为“QuotesMakeItCaseSensitive”。只是后来我要转义双引号,sql开始看起来很粗糙,不再是轻量级了。我确实认为我可以在 IDictionary鉴于查询结果可以转换为IDictionary<string, object>
,只需转换每个动态结果,然后调用如下方法:
public static IDictionary<string, T> ToCaseInsensitiveDictionary<T>(this IDictionary<string, T> source)
var target = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
foreach (var entry in source)
target[entry.Key] = entry.Value;
return target;
示例用法:
var results = connection.Query(sql);
foreach (IDictionary<string, object> rawResult in results)
var result = rawResult.ToCaseInsensitiveDictionary();
var column = result["MY_COLUMN"]; // or result["My_Column"] etc.
【讨论】:
以上是关于如何让 Dapper 动态不区分大小写?的主要内容,如果未能解决你的问题,请参考以下文章