【发布时间】:2019-05-03 07:18:00
【问题描述】:
我有一个动态对象,它基本上包含一个 AvroRecord。 AvroRecord 课程详情here.
我可以静态地为属性赋值,但我想知道这是否可以动态地完成。我查看了论坛问题here、here 和here。但这些都不适合我。
这是有效的静态代码。
var serializer = AvroSerializer.CreateGeneric(Schema);
var rootSchema = serializer.WriterSchema as RecordSchema;
dynamic counterpartRow = new AvroRecord(rootSchema);
counterpartRow.CounterpartID = Row.CounterpartID
counterpartRow.CounterpartFirstDepositDate = Row.CounterpartFirstDepositDate
Row 是 SSIS 的 InputBuffer 类的一个对象,它包含来自上游数据源的所有列。
上面使用的 schema 变量是一个 avro schema,大概是这样的。
Schema = @"{
""type"":""record"",
""name"":""Microsoft.Hadoop.Avro.Specifications.Counterparts"",
""fields"":
[
{ ""name"":""CounterpartID"", ""type"":""int"" },
{ ""name"":""CounterpartFirstDepositDate"", ""type"":[""string"",""null""] },
{ ""name"":""CounterpartFirstTradeDate"",""type"":[""string"",""null""] },
{ ""name"":""ClientSegmentReportingID"",""type"":""int"" },
{ ""name"":""ClientSegmentReportingName"", ""type"":[""string"",""null""] },
{ ""name"":""ContractID"", ""type"":""int""},
{ ""name"":""ContractFirstDepositDate"", ""type"":[""string"",""null""]},
{ ""name"":""ContractFirstTradeDate"",""type"":[""string"",""null""] },
{ ""name"":""ContractClosingOffice"",""type"":[""string"",""null""] },
{ ""name"":""LeadCreationDate"", ""type"":[""string"",""null""] },
{ ""name"":""ContractCountryOfResidence"", ""type"":[""string"",""null""]}
]
}";
我尝试过类似早期论坛链接的建议,如
counterpartRow.GetType().GetField("CounterpartID").SetValue(Row, Row.CounterpartID, null);
还有另一种方法(显然应该适用于动态类型),但即使这样也不行。
foreach (string propertyName in GetPropertyKeysForDynamic(counterpartRow.Schema.Fields()))
{
string propertyValue = counterpartRow[propertyName];
}
和这样定义的函数。
public List<string> GetPropertyKeysForDynamic(dynamic dynamicToGetPropertiesFor)
{
var jObject = (JObject)JToken.FromObject(dynamicToGetPropertiesFor);
Dictionary<string, object> values = jObject.ToObject<Dictionary<string, object>>();
List<string> toReturn = new List<string>();
foreach (string key in values.Keys)
{
toReturn.Add(key);
}
return toReturn;
}
上面的字典返回空白。
上面提到的Row是InputBuffer类(SSIS中自动生成的类)的一个对象。
是这样的。
public class Input0Buffer: ScriptBuffer
{
public Input0Buffer(PipelineBuffer Buffer, int[] BufferColumnIndexes, OutputNameMap OutputMap)
: base(Buffer, BufferColumnIndexes, OutputMap)
{
}
public Int32 CounterpartID
{
get
{
return Buffer.GetInt32(BufferColumnIndexes[0]);
}
}
------more properties
如果您看到我的原始静态代码,我正在尝试动态生成分配。我已经动态生成了模式(而不是我上面给出的静态定义)。所以,唯一剩下要动态生成的就是assignment的assignment了。一个想法可能是我生成字符串,但我如何执行该字符串?只有在没有办法实现这一点的情况下。
【问题讨论】:
-
Dynamic 只是一个在运行时接受任何类型的关键字。您实际上并没有动态对象,而是 AvroRecord 类型。你得看看这个类型是怎么操作的。
-
感谢您的回复。是的,我知道,但也许这个问题的标题框架不是最合适的。无论如何,我希望我提供的第三个链接有效:*.com/questions/2634858/…。但事实并非如此。 AvroRecord 扩展 DynamicObject 和 DynamicObject 实现 IDynamicMetaObjectProvider。无论如何,我将阅读有关 DynamicObject 类(AvroRecord 扩展)的更多信息。
标签: c# reflection ssis