vendredi 3 août 2018

C# Covert Type into IEnumerable of same Type?

I have some methods that execute arbitrary SQL against a database and serialize that data collection into a list of a concrete type. That data is then serialized into JSON and stored in a cell in a table. Later, I need to come back and deserialize that data back into its original collection so that it can be used.

I'm having some issues figuring out how to take a Type object and create a collection of that type in order to deserialize it. Here is how my code operates:

public async Task ExecuteWidget(Guid runGuid, string widgetName, Type type, string sql,
    IEnumerable<SqlParameter> parameters)
{
    var report = operationsContext.ReportRuns.FirstOrDefault(n => n.RunGuid == runGuid);

    CheckReportStatus(report);

    var param = parameters.ToList();
    var result = edwContext.Database.SqlQuery(type, sql, param.ToArray<object>());
    var query = result.GetQuery(param);
    var data = await result.ToListAsync();
    var widgetData = new ReportRunWidgetData()
    {
        ReportRunId = report?.ReportRunId ?? -1, // This should never be null.
        WidgetName = widgetName,
        WidgetData = new JavaScriptSerializer().Serialize(data),
        Query = query
    };

    operationsContext.ReportRunWidgetDatas.Add(widgetData);
    await operationsContext.SaveChangesAsync();
}

My fetching logic looks something like this:

public object FetchWidgetData(Guid runGuid, string widgetName, Type dataType)
{
    var data = operationsContext.ReportRuns
        .Include("ReportRunWidgetDatas")
        .FirstOrDefault(n => n.RunGuid == runGuid)?
        .ReportRunWidgetDatas.FirstOrDefault(n => n.WidgetName == widgetName)?
        .WidgetData;

    if (data == null) return null;

    var deserialized = new JavaScriptSerializer().Deserialize(data, dataType);

    return deserialized;
}

Now when the ExecuteWidget method is called, the type parameter is populated by the widget's DTO datatype. For example HeadlineWidgetDTO. However, the execute command gets the data back as a List<HeadlineWidgetDTO>. When my FetchWidgetData method is called, the dataType supplied is still HeadlineWidgetDTO, but it actually needs to be of type IEnumerable<HeadlineWidgetDTO> to deserialize properly.

Given just the type for an individual data row, how can I create a Type object that is instead a collection of that type?





Aucun commentaire:

Enregistrer un commentaire