我正在尝试设计一个进行提取转换加载操作的过程。我想在我的管道中使用 ExpandoObject 以允许我轻松地将列添加到我的数据流中。基本上,我从某种数据源读取数据,将其转换为动态并将其返回到转换管道,该转换管道基于现有属性或其他内容向其添加属性,然后将其流式传输到数据库中。
我遇到的问题是,即使我添加了 Nullable 类型,我也需要添加到我的 expando 对象的所有属性的类型信息。如果 Nullable 类型由于值的装箱而为 null,则会丢失。我想要类型信息,以便在我的管道结束时我可以在我的 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 中找出类型?我想知道是否有某种方法可以使用某种表达树的魔法?
如果有人有任何好主意,我很想听听。除了可以为空的类型之外,这一切都很好,但它们是数据库操作的关键。
谢谢