2

I have a dynamic object which basically holds an AvroRecord. AvroRecord class details here.

I can assign values to the properties statically but I was wondering if this could be done dynamically. I have looked at the forum question here ,here and also here. But none of these work for me.

This is the static code that works.

    var serializer = AvroSerializer.CreateGeneric(Schema);
    var rootSchema = serializer.WriterSchema as RecordSchema;
    dynamic counterpartRow = new AvroRecord(rootSchema);
    counterpartRow.CounterpartID = Row.CounterpartID
    counterpartRow.CounterpartFirstDepositDate = Row.CounterpartFirstDepositDate

The Row is an object of the InputBuffer class of SSIS and it holds all the columns coming from the upstream data source.

The schema variable used above is an avro schema, which is something like this.

 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""]}
                                    ]
                            }";

I have tried something like the earlier forum links suggested like

counterpartRow.GetType().GetField("CounterpartID").SetValue(Row, Row.CounterpartID, null);

and also the other method (which apparently should work for for dynamic type), but even that does not.

foreach (string propertyName in GetPropertyKeysForDynamic(counterpartRow.Schema.Fields()))
        {
            string propertyValue = counterpartRow[propertyName];


        }

and the function defined like this.

 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;
    }

The dictionary above returns blank.

the Row mentioned above is an object of InputBuffer class (auto generated class in SSIS).

which is something like this.

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

If you see my original static code, I am trying to dynamically generate the assignment. I have already dynamically generated the schema (instead of the static definition I have given above). So, the only piece left to generate dynamically is the assignment of the assignment. An idea could be that I generate the string but how do I then execute that string? That is only if there is no way to achieve this.

Saugat Mukherjee
  • 778
  • 8
  • 32
  • Dynamic is just a keyword accepting any type at runtime. You don't really have a dynamic object but of type AvroRecord. You have to see how this type is operated. – Roland Buergi May 03 '19 at 08:04
  • Thanks for your response. Yes, I know but maybe the framing of the title of this question isn't the most appropriate. Anyways, I would have expected the third link I provided to have worked : https://stackoverflow.com/questions/2634858/how-do-i-reflect-over-the-members-of-dynamic-object#comment80831329_39091755. But it doesn't. AvroRecord extends DynamicObject and DynamicObject implements IDynamicMetaObjectProvider. anyways, I will read more about the DynamicObject class (which AvroRecord extends). – Saugat Mukherjee May 03 '19 at 08:57

1 Answers1

0

If I understand correct your question I think you can try something like this

        string _schema = "your avro schema"
        RecordSchema _record = (RecordSchema)Avro.Schema.Parse(_schema);
        GenericRecord _generic_record = new GenericRecord(payload_record);
        for (int ii = 0; ii < _record.Fields.Count; ii++)
        {
            _generic_record.Add(_record.Fields[ii].Name, Raw.TheFiledYouNeed);
        }
Inako
  • 259
  • 5
  • 13