Last active
January 29, 2016 09:38
-
-
Save jhgbrt/ed8921d43c49da70a341 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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