Last active
August 29, 2015 14:13
-
-
Save TWolverson/a0446603654abaeb4114 to your computer and use it in GitHub Desktop.
Micro ORM as single method
This file contains hidden or 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 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; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.