using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using Fasterflect;
namespace DataModel.Helpers
{
///
/// IEnumerable extension helpers
///
public static class GenericListDataReaderExtensions
{
///
/// Generates generic data reader for bulk copies from list
///
/// Element data type
/// Source list
/// Data reader to parse list contents
public static GenericListDataReader GetDataReader(this IEnumerable list) where T : class
{
return new GenericListDataReader(list);
}
}
///
/// Data reader that parses list of generic elements
///
public class GenericListDataReader : IDataReader
{
public int Count { get; set; }
private readonly IEnumerator list = null;
private readonly List properties = new List();
private readonly Dictionary nameLookup = new Dictionary();
private readonly string[] propertyNames;
public GenericListDataReader(IEnumerable list, Type type)
{
this.list = list.GetEnumerator();
properties.AddRange(type.GetProperties(BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly));
propertyNames = new string[properties.Count];
for (int i = 0; i < properties.Count; i++)
{
nameLookup[properties[i].Name] = i;
propertyNames[i] = properties[i].Name;
}
}
public void Close()
{
list.Dispose();
}
public int Depth => throw new NotImplementedException();
public DataTable GetSchemaTable()
{
throw new NotImplementedException();
}
public bool IsClosed => false;
public bool NextResult()
{
throw new NotImplementedException();
}
public bool Read()
{
bool readResult = list.MoveNext();
//Update counter
if (readResult)
{
Count++;
}
return readResult;
}
public int RecordsAffected => throw new NotImplementedException();
public void Dispose()
{
Close();
}
public int FieldCount => properties.Count;
public bool GetBoolean(int i)
{
return (bool)GetValue(i);
}
public byte GetByte(int i)
{
return (byte)GetValue(i);
}
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}
public char GetChar(int i)
{
return (char)GetValue(i);
}
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}
public IDataReader GetData(int i)
{
throw new NotImplementedException();
}
public string GetDataTypeName(int i)
{
throw new NotImplementedException();
}
public DateTime GetDateTime(int i)
{
return (DateTime)GetValue(i);
}
public decimal GetDecimal(int i)
{
return (decimal)GetValue(i);
}
public double GetDouble(int i)
{
return (double)GetValue(i);
}
public Type GetFieldType(int i)
{
return properties[i].PropertyType;
}
public float GetFloat(int i)
{
return (float)GetValue(i);
}
public Guid GetGuid(int i)
{
return (Guid)GetValue(i);
}
public short GetInt16(int i)
{
return (short)GetValue(i);
}
public int GetInt32(int i)
{
return (int)GetValue(i);
}
public long GetInt64(int i)
{
return (long)GetValue(i);
}
public string GetName(int i)
{
return properties[i].Name;
}
public int GetOrdinal(string name)
{
if (nameLookup.ContainsKey(name))
{
return nameLookup[name];
}
else
{
return -1;
}
}
public string GetString(int i)
{
return (string)GetValue(i);
}
public object GetValue(int i)
{
string name = propertyNames[i];
return list.Current.GetPropertyValue(name);
}
public int GetValues(object[] values)
{
int getValues = Math.Max(FieldCount, values.Length);
for (int i = 0; i < getValues; i++)
{
values[i] = GetValue(i);
}
return getValues;
}
public bool IsDBNull(int i)
{
return GetValue(i) == null;
}
public object this[string name] => list.Current.GetPropertyValue(name);
public object this[int i] => GetValue(i);
}
///
/// Data reader that parses list of generic elements
///
/// Element data type
public class GenericListDataReader : GenericListDataReader where T : class
{
public GenericListDataReader(IEnumerable list)
: base(list, typeof(T))
{
}
}
}