Skip to content

Instantly share code, notes, and snippets.

@TWolverson
Last active August 29, 2015 14:13
Show Gist options
  • Save TWolverson/a0446603654abaeb4114 to your computer and use it in GitHub Desktop.
Save TWolverson/a0446603654abaeb4114 to your computer and use it in GitHub Desktop.
Micro ORM as single method
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication6
{
public delegate void ParseDelegate<T>(DbDataReader reader, ref T obj);
public class FakeDataReader : DbDataReader
{
public FakeDataReader(params object[] fakeResults)
: base()
{
this.fakeResults = fakeResults;
this.properties = fakeResults[0].GetType().GetProperties();
}
private PropertyInfo[] properties;
private object[] fakeResults;
private int readerIndex = -1;
public override bool Read()
{
readerIndex++;
return readerIndex < fakeResults.Length;
}
public override object this[string name]
{
get
{
return properties.Single(p => p.Name == name).GetValue(fakeResults[readerIndex]);
}
}
public override void Close()
{
throw new NotImplementedException();
}
public override int Depth
{
get { throw new NotImplementedException(); }
}
public override int FieldCount
{
get { throw new NotImplementedException(); }
}
public override bool GetBoolean(int ordinal)
{
throw new NotImplementedException();
}
public override byte GetByte(int ordinal)
{
throw new NotImplementedException();
}
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
{
throw new NotImplementedException();
}
public override char GetChar(int ordinal)
{
throw new NotImplementedException();
}
public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
{
throw new NotImplementedException();
}
public override string GetDataTypeName(int ordinal)
{
throw new NotImplementedException();
}
public override DateTime GetDateTime(int ordinal)
{
throw new NotImplementedException();
}
public override decimal GetDecimal(int ordinal)
{
throw new NotImplementedException();
}
public override double GetDouble(int ordinal)
{
throw new NotImplementedException();
}
public override System.Collections.IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
public override Type GetFieldType(int ordinal)
{
throw new NotImplementedException();
}
public override float GetFloat(int ordinal)
{
throw new NotImplementedException();
}
public override Guid GetGuid(int ordinal)
{
throw new NotImplementedException();
}
public override short GetInt16(int ordinal)
{
throw new NotImplementedException();
}
public override int GetInt32(int ordinal)
{
throw new NotImplementedException();
}
public override long GetInt64(int ordinal)
{
throw new NotImplementedException();
}
public override string GetName(int ordinal)
{
throw new NotImplementedException();
}
public override int GetOrdinal(string name)
{
throw new NotImplementedException();
}
public override DataTable GetSchemaTable()
{
var table = new DataTable();
foreach (var property in properties)
{
table.Columns.Add(new DataColumn(property.Name));
}
return table;
}
public override string GetString(int ordinal)
{
throw new NotImplementedException();
}
public override object GetValue(int ordinal)
{
throw new NotImplementedException();
}
public override int GetValues(object[] values)
{
throw new NotImplementedException();
}
public override bool HasRows
{
get { throw new NotImplementedException(); }
}
public override bool IsClosed
{
get { throw new NotImplementedException(); }
}
public override bool IsDBNull(int ordinal)
{
throw new NotImplementedException();
}
public override bool NextResult()
{
throw new NotImplementedException();
}
public override int RecordsAffected
{
get { throw new NotImplementedException(); }
}
public override object this[int ordinal]
{
get { throw new NotImplementedException(); }
}
}
public class DomainType
{
public string Foo { get; set; }
public string Bar { get; set; }
public string Baz { get; set; }
}
class Program
{
static void Main(string[] args)
{
var fakeReader = new FakeDataReader(new DomainType { Foo = "Hello", Bar = "Goodbye", Baz = "Bacon" }, new DomainType { Foo = "Goodbyte", Bar = "Hello", Baz = "Bacon" });
foreach (var result in GetValues<DomainType>(fakeReader))
{
Console.WriteLine(JsonConvert.SerializeObject(result));
}
Console.Read();
}
static IEnumerable<T> GetValues<T>(DbDataReader reader) where T : class
{
var parse = from column in reader.GetSchemaTable().Columns.Cast<DataColumn>()
join property in typeof(T).GetProperties() on column.ColumnName equals property.Name
select new ParseDelegate<T>((DbDataReader r, ref T obj) =>
{
obj = obj ?? Activator.CreateInstance<T>();
property.SetValue(obj, reader[property.Name]);
});
while (reader.Read())
{
T obj = null;
foreach (var parser in parse)
{
parser(reader, ref obj);
}
yield return obj;
}
yield break;
}
}
}
@TWolverson
Copy link
Author

The cheap and shoddy fake data source is terrible, pay as little attention as you can to it. It's solely so that I don't have to go to the trouble of building a real database to test against.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment