I have list of object arrays (List<object[]> sourcedata
) that come from different sources (files, sql, webservices) and I need a way to join/union them, group by, select, where and calculate new columns,...
The user select the sourcedatas (List<object[]>
) from a large list of them, and I need a way to transform all of them in one List and I need a way to express that transformation in order the user can write it dinamically depending in his neededs.
I don't know if there is a simple way using dynamic linq. The user who write the expression have knowledge about c# and linq so he could write some linq code at execution time.
Some data would come from Relational databases:
internal async override Task<IEnumerable<dynamic[]>> ExecuteAsync(IEnumerable<Parameter> parameters)
{
List<object[]> returnValue = new List<object[]>();
using (var conn = new SqlConnection(((MicrosoftSQLServerDataSource)this.DataSource).ConnectionString))
{
var queryParametized = this.prepareSqlQuery(this.SqlQuery, parameters);
using (var query = new SqlCommand(queryParametized.Item1, conn))
{
query.Parameters.AddRange(queryParametized.Item2);
try
{
await conn.OpenAsync();
using (DbDataReader reader = await query.ExecuteReaderAsync())
{
while (reader.Read())
{
object[] row;
if (this.Columns != null && this.Columns.Count > 0)
{
row = new object[this.Columns.Count];
foreach (var col in this.Columns)
{
row[col.Index] = this.ConvertData(reader[col.Index], col);
}
}
else
{
row = new object[reader.FieldCount];
for (int i = 0; i < reader.FieldCount; i++)
{
row[i] = reader.GetValue(i);
}
}
returnValue.Add(row);
}
}
}
finally
{
if (conn != null && conn.State != System.Data.ConnectionState.Closed)
conn.Close();
}
}
}
return returnValue;
}
An other from webservices:
private IEnumerable<dynamic[]> Execute(IEnumerable<Parameter> parameters)
{
List<object[]> returnValue = new List<object[]>();
//Nos logueamos en OBIEE y obtenemos un identificador de sesion
//TODO: LLevar un pool de conexiones
SAWSessionServiceSoapClient sService = new SAWSessionServiceSoapClient();
//Modificamos la url del servicio web segun este configurada en el dataquery
sService.Endpoint.Address = new System.ServiceModel.EndpointAddress(this.DataSource.urlWSDL + "?SoapImpl=nQSessionService");
string sessionID = sService.logon(this.DataSource.User, this.DataSource.Password);
//Ejecutamos la sql logica del dataquery
XmlViewServiceSoapClient sqlExecuter = new XmlViewServiceSoapClient();
//Modificamos la url del servicio web segun este configurada en el dataquery
sqlExecuter.Endpoint.Address = new System.ServiceModel.EndpointAddress(this.DataSource.urlWSDL + "?SoapImpl=xmlViewService");
QueryResults resultsData = sqlExecuter.executeSQLQuery(this.getSql(this.LogicalSql, parameters), XMLQueryOutputFormat.SAWRowsetData, new XMLQueryExecutionOptions(), sessionID);
//Cerramos sesion
sService.logoff(sessionID);
//Parseamos el xml de salida
XDocument doc = XDocument.Load(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(resultsData.rowset)));
XNamespace ns = @"urn:schemas-microsoft-com:xml-analysis:rowset";
returnValue = (from rows in doc.Root.Descendants(ns + "Row")
select (from columns in rows.Elements() select (object)columns.Value).ToArray()
).ToList();
return returnValue;
}
And we want let the user merge both data freely.
Any idea? Thanks