26ff8d9b4f
Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
234 lines
5.9 KiB
C#
Executable File
234 lines
5.9 KiB
C#
Executable File
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Reflection;
|
|
using Fasterflect;
|
|
|
|
namespace DataModel.Helpers
|
|
{
|
|
/// <summary>
|
|
/// IEnumerable extension helpers
|
|
/// </summary>
|
|
public static class GenericListDataReaderExtensions
|
|
{
|
|
/// <summary>
|
|
/// Generates generic data reader for bulk copies from list
|
|
/// </summary>
|
|
/// <typeparam name="T">Element data type</typeparam>
|
|
/// <param name="list">Source list</param>
|
|
/// <returns>Data reader to parse list contents</returns>
|
|
public static GenericListDataReader<T> GetDataReader<T>(this IEnumerable<T> list) where T : class
|
|
{
|
|
return new GenericListDataReader<T>(list);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Data reader that parses list of generic elements
|
|
/// </summary>
|
|
public class GenericListDataReader : IDataReader
|
|
{
|
|
public int Count { get; set; }
|
|
private readonly IEnumerator<object> list = null;
|
|
private readonly List<PropertyInfo> properties = new List<PropertyInfo>();
|
|
private readonly Dictionary<string, int> nameLookup = new Dictionary<string, int>();
|
|
private readonly string[] propertyNames;
|
|
|
|
public GenericListDataReader(IEnumerable<object> 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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Data reader that parses list of generic elements
|
|
/// </summary>
|
|
/// <typeparam name="T">Element data type</typeparam>
|
|
public class GenericListDataReader<T> : GenericListDataReader where T : class
|
|
{
|
|
public GenericListDataReader(IEnumerable<T> list)
|
|
: base(list, typeof(T))
|
|
{
|
|
|
|
}
|
|
}
|
|
} |