I'm using Dapper with Oracle. Oracle query results columns are case insensitive (unless you double-quote them), and Oracle returns the column names in uppercase. And so when using dynamic, Dapper requires using uppercase fieldnames.
Is there a way to make Dapper not care about case when using Dynamic? I see in DapperTable http://dapper-dot-net/Dapper/SqlMapper.DataTable.cs that it uses a Dictionary with StringComparer.Ordinal instead of StringComparer.OrdinalIgnoreCase, and I don't see any options to change it. But I am hoping somebody has a solution for this, or can tell me how to do it in a better way.
Example:
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.
Edit:
See this answer for maybe an alternative way to enumerate through the properties to do something similar to what I have below (you might be able to cast the dynamic
as an IDictionary<string,object>
).
Also (not familiar enough with Oracle to know if this is true, or not) but maybe if you aliased the column name in the SELECT query (i.e. using AS
in T-SQL) that would override the casing?
Original:
(Marc Gravell said the following wouldn't work with Dapper.)
Does adapting the idea from this answer work (untested with Dapper, specifically)?
using NUnit.Framework;
using System;
using System.Collections.Generic;
namespace StackOverflowSandbox
{
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://stackoverflow.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;
}
}
}