Skip to content

Instantly share code, notes, and snippets.

@bmeredith
Last active September 10, 2019 20:12
Show Gist options
  • Save bmeredith/f3fb3928fefcc31e686e8edaaff6a254 to your computer and use it in GitHub Desktop.
Save bmeredith/f3fb3928fefcc31e686e8edaaff6a254 to your computer and use it in GitHub Desktop.
// 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