Skip to content

Instantly share code, notes, and snippets.

@jhgbrt
Last active January 29, 2016 09:38
Show Gist options
  • Save jhgbrt/ed8921d43c49da70a341 to your computer and use it in GitHub Desktop.
Save jhgbrt/ed8921d43c49da70a341 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Reflection;
namespace Tools
{
public static class ListDataReader
{
public static DbDataReader AsDataReader<T>(this IEnumerable<T> input)
{
return new ListDataReader<T>(input);
}
}
/// <summary>
/// Adapter from IEnumerable[T] to IDataReader
/// </summary>
/// <typeparam name="T"></typeparam>
public class ListDataReader<T> : DbDataReader
{
private readonly IEnumerable<T> _list;
private readonly IEnumerator<T> _enumerator;
// ReSharper disable StaticFieldInGenericType
private static readonly PropertyInfo[] Properties;
private static readonly Lazy<IDictionary<string, int>> PropertyIndexesByName
= new Lazy<IDictionary<string, int>>(() => Properties.Select((p, i) => new { p, i }).ToDictionary(x => x.p.Name, x => x.i));
// ReSharper restore StaticFieldInGenericType
static ListDataReader()
{
var propertyInfos = from property in typeof(T).GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public)
where property.PropertyType.IsPrimitive || property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(string)
select property;
Properties = propertyInfos.ToArray();
}
public ListDataReader(IEnumerable<T> list)
{
_list = list;
_enumerator = _list.GetEnumerator();
}
public override string GetName(int i) => Properties[i].Name;
public override string GetDataTypeName(int i) => GetFieldType(i).Name;
public override IEnumerator GetEnumerator() => _enumerator;
public override Type GetFieldType(int i) => Properties[i].PropertyType;
public override object GetValue(int i)
{
var current = _enumerator.Current;
var o = Properties[i].GetValue(current, null);
return o == null || DBNull.Value.Equals(o) ? null : o;
}
public override int GetValues(object[] values)
{
var current = _enumerator.Current;
var n = Math.Min(FieldCount, values.Length);
for (int i = 0; i < n; i++)
values[i] = GetValue(i);
return n;
}
public override int GetOrdinal(string name)
{
return PropertyIndexesByName.Value[name];
}
public override bool GetBoolean(int i)
{
throw new NotSupportedException();
}
public override byte GetByte(int i)
{
throw new NotSupportedException();
}
public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
throw new NotSupportedException();
}
public override char GetChar(int i)
{
throw new NotSupportedException();
}
public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
throw new NotSupportedException();
}
public override Guid GetGuid(int i)
{
throw new NotSupportedException();
}
public override short GetInt16(int i)
{
throw new NotSupportedException();
}
public override int GetInt32(int i)
{
throw new NotSupportedException();
}
public override long GetInt64(int i)
{
throw new NotSupportedException();
}
public override float GetFloat(int i)
{
throw new NotSupportedException();
}
public override double GetDouble(int i)
{
throw new NotSupportedException();
}
public override string GetString(int i)
{
throw new NotSupportedException();
}
public override decimal GetDecimal(int i)
{
throw new NotSupportedException();
}
public override DateTime GetDateTime(int i)
{
throw new NotSupportedException();
}
public override bool IsDBNull(int i) => DBNull.Value.Equals(GetValue(i));
public override int FieldCount => Properties.Length;
public override bool HasRows => _list.Any();
public override object this[int i] => GetValue(i);
public override object this[string name] => GetValue(GetOrdinal(name));
public DataTable GetSchemaTable()
{
throw new NotSupportedException();
}
public override bool NextResult() => false;
public override bool Read() => _enumerator.MoveNext();
public override int Depth => 0;
public override bool IsClosed => false;
public override int RecordsAffected => 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment