如何让 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。在不改变 Dapper 本身的情况下,这似乎是最好的解决方案。【参考方案2】:

鉴于查询结果可以转换为IDictionary&lt;string, object&gt;,只需转换每个动态结果,然后调用如下方法:

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 动态不区分大小写?的主要内容,如果未能解决你的问题,请参考以下文章

如何让mysql的表名/字段名/字段值区分大小写

如何查看mysql表名字段是不是区分大小写

如何使用 htmx 在 django 中进行不区分大小写的主动搜索

如何在 Java 中替换不区分大小写的文字子字符串

linux中awk处理文本时如何让它不区分大小写?

Jquery 让contains不区分大小写