Last active
September 10, 2019 20:12
-
-
Save bmeredith/f3fb3928fefcc31e686e8edaaff6a254 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
// uses the nuget package: | |
// https://www.nuget.org/packages/System.Linq.Dynamic.Core/ | |
// | |
// the real magic comes from here: | |
// https://github.com/StefH/System.Linq.Dynamic.Core/blob/master/src/System.Linq.Dynamic.Core/DynamicClassFactory.cs | |
public class DynamicSqlObjectFactory | |
{ | |
// this will return a DynamicClass object which can be manipulated using straight reflection | |
// or using any of System.Dynamic.DynamicObject's methods as well | |
public DynamicClass Create(IDictionary<string, object> item, IEnumerable<DatabaseColumn> fields) | |
{ | |
if (item == null) | |
throw new ArgumentNullException(nameof(item)); | |
var sortedFields = fields.OrderBy(f => f.FieldName).ToList(); | |
var sortedDict = new SortedDictionary<string, object>(item); | |
var dynamicType = CreateType(sortedFields); | |
return CreateClass(sortedDict, sortedFields, dynamicType); | |
} | |
private static Type CreateType(IEnumerable<DatabaseColumn> fields) | |
{ | |
var properties = new List<DynamicProperty>(); | |
foreach (var field in fields) | |
{ | |
var fieldType = SqlTypeConverter.ToNetType(field.DataType, field.IsNullable); | |
properties.Add(new DynamicProperty(field.FieldName, fieldType)); | |
} | |
return DynamicClassFactory.CreateType(properties); | |
} | |
private static DynamicClass CreateClass(IDictionary<string, object> item, IEnumerable<DatabaseColumn> fields, Type dynamicType) | |
{ | |
var values = Array.ConvertAll(item.ToArray(), x => x.Value); | |
var valueTypes = fields.Select(x => SqlTypeConverter.ToNetType(x.DataType, x.IsNullable)).ToArray(); | |
return dynamicType.GetConstructor(valueTypes)?.Invoke(values) as DynamicClass; | |
} | |
} | |
public class DatabaseColumn | |
{ | |
public SqlDbType DataType { get; set; } | |
public string FieldName { get; set; } | |
public bool IsNullable { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment