Я пытаюсь создать процесс для выполнения операций загрузки извлечения. Я хочу использовать ExpandoObject в моем конвейере, чтобы позволить мне легко добавлять столбцы в поток данных. В основном я читаю данные из какого-то источника данных, которые придают ему динамический характер и возвращают его в конвейер преобразований, которые добавляют к нему свойства либо на основе существующих свойств, либо что-то еще, а затем передают его в базу данных.Информация о типе хранилища с DynamicObject
Проблема в том, что мне нужна информация о типе для всех свойств, которые я добавляю к моему объекту expando, даже если я добавляю тип Nullable. Это потеряно, если тип Nullable является нулевым из-за бокса значения. Мне нужна информация о типе, чтобы в конце моего конвейера я мог реализовать datareader над моим перечислением ExpandoObjects и передать данные в базу данных.
Я надеялся, что свойство SetMemberBinder.ReturnType может помочь мне, но, похоже, возвращает объект.
вот некоторые примеры кода:
using System;
using System.Collections.Generic;
using System.Dynamic;
using Xunit
namespace Whanger
{
public class MyExpando : DynamicObject
{
Dictionary<string, object> properties = new Dictionary<string, object>();
Dictionary<string, Type> propertyTypes = new Dictionary<string, Type>();
public Dictionary<string, Type> Types
{
get
{
return propertyTypes;
}
}
public Dictionary<string, object> Values
{
get
{
return properties;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (properties.ContainsKey(binder.Name))
{
result = properties[binder.Name];
return true;
}
else
{
result = null;
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
properties[binder.Name] = value;
propertyTypes[binder.Name] = binder.ReturnType;//always object :(
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
dynamic method = properties[binder.Name];
result = method(args[0].ToString(), args[1].ToString());
return true;
}
}
public class MyExpandoTests
{
[Fact]
public void CanAddDynamicMembers()
{
dynamic obj = new MyExpando();
obj.Name = "Wibble";
obj.Value = 2;
Assert.Equal(obj.Name, "Wibble");
Assert.Equal(obj.Value, 2);
}
[Fact]
public void CanMaintainType()
{
dynamic obj = new MyExpando();
int? nullableInt = null;
obj.NullInt = nullableInt;
obj.Name = "Wibble";
Assert.Equal(obj.Name, "Wibble");
Assert.Null(obj.NullInt);
//fails
Assert.Equal(typeof(int?), ((MyExpando)obj).Types["NullInt"]);
}
}
}
Есть ли способ узнать тип из TrySetMember? Интересно, можно ли каким-то образом использовать магию дерева выражений?
Если у кого-то есть отличные идеи, я бы хотел их услышать. Все это работает хорошо, за исключением типов с нулевым значением, но они являются ключевыми для операций с базой данных.
Благодаря
Хотя это явно не указано, это может представлять интерес: ['System.Dynamic.ExpandObject'] (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject%28v=vs. 110% 29.aspx) – heltonbiker
'ExpandoObject' - это просто словарь объектов, также может быть размещена нулевая структура. – IllidanS4