Arjuna Aircraft Ident.: F-MBSD | => dans le dernier code que j'ai posté en date, non, il est toujours présent le gogo.
=> pour les fonction, je suis d'accord que ça deviens un peu usine à gaz. ceci dit, c'est carrément du oneshot à chaque fois : même si parfois je fais deux fois un traîtement similaire, il y a suffisament de différences pour ne pas le rendre factorisable. du coup j'ai tout laissé en pense de vache, mais je ne vois pas comment faire mieux, du moins si je veux conserver le peu d'optimisations qu'il y a dans le code...
sinon, voici ma bidouille pour contourner le problème du fillschema... d'un côté, j'ai fortement optimisé le code, et surtout, il n'y a plus de goto... mais d'un autre côté, là je lance systématiquement la requête une première fois sans filtre ! du coup je vous raconte pas les perfs si y'a beaucoup de ligne
j'espère qu'une bonne âme voudra bien me donner une explication de ce "bug" de fillschema, afin de retrouver un semblant de performances dans mon truc...
du coup, j'en suis à me demander si ce ne serait pas plus simple de tout charger, et de faire les filtres dans le DataTable au lieu de les faire en SQL. A priori, ça serait pas moins performant
Voilà le code complet qui marche.
Y'a plus de bugs. Et je peux mettre à jour n'importe quelle requête du moment qu'il n'y a pas d'agrégations dedans (ni de jointures complexes, ça va de soit)
Code :
- SqlCommand cmd = cnx.CreateCommand();
- string sql = string.Format("select * from ({0}) res", xmlDefinition.SelectSingleNode("view/sql" ).InnerText);
- cmd.CommandText = sql;
- cmd.CommandType = CommandType.Text;
- cmd.Prepare();
- DataTable dts = new DataTable();
- SqlDataAdapter das = new SqlDataAdapter(cmd);
- das.Fill(dts);
- das.FillSchema(dts, SchemaType.Source);
- bool addRow = false;
- bool delRow = false;
- // Insert
- DataRow newRow = null;
- foreach (string param in Request.Params.Keys)
- {
- if (param != null && param.StartsWith(string.Format("add:{0}-", viewName)) && Request.Params[param] != string.Empty)
- {
- addRow = true;
- break;
- }
- }
- if (addRow)
- {
- bool notNullRow = false;
- newRow = dts.NewRow();
- foreach (DataColumn col in dts.Columns)
- {
- foreach (string param in Request.Params.Keys)
- {
- if (param != null && param == string.Format("add:{0}-{1}", viewName, col.ColumnName))
- {
- switch (col.DataType.Name)
- {
- case "String":
- if (Request.Params[string.Format("add:{0}-{1}", viewName, col.ColumnName)].ToString() != string.Empty)
- {
- notNullRow = true;
- newRow[col] = Request.Params[string.Format("add:{0}-{1}", viewName, col.ColumnName)].ToString();
- }
- break;
- }
- break;
- }
- }
- }
- if (notNullRow)
- {
- dts.Rows.Add(newRow);
- }
- else
- {
- newRow = null;
- }
- }
- // Delete
- foreach (string param in Request.Params.Keys)
- {
- if (param != null && param == string.Format("del:{0}", viewName))
- {
- delRow = true;
- break;
- }
- }
- if (delRow)
- {
- // Primary keys retrieve
- foreach (string lineId in Request.Params[string.Format("del:{0}", viewName)].Split(','))
- {
- bool deleted = false;
- string[] keys = Request.Params[string.Format("pk:{0}-{1}", viewName, lineId)].Split(',');
- foreach (DataRow row in dts.Rows)
- {
- if (row.RowState != DataRowState.Deleted)
- {
- bool wouldDelete = true;
- for (int i = 0; i < keys.Length; i++)
- {
- if (row[dts.PrimaryKey[i]].ToString() != keys[i].Substring(1, keys[i].Length - 2))
- {
- wouldDelete = false;
- break;
- }
- }
- if (wouldDelete)
- {
- row.Delete();
- deleted = true;
- }
- if (deleted)
- {
- break;
- }
- }
- }
- }
- }
- // Update
- foreach (DataRow row in dts.Rows)
- {
- if (row.RowState != DataRowState.Deleted)
- {
- foreach (DataColumn col in dts.Columns)
- {
- // Primary keys retrieve
- foreach (string param in Request.Params.Keys)
- {
- bool updated = false;
- if (param != null && param.StartsWith(string.Format("upd:{0}-{1}-", viewName, col.ColumnName)))
- {
- bool wouldUpdate = true;
- string lineId = param.Substring(param.LastIndexOf('-') + 1);
- string[] keys = Request.Params[string.Format("pk:{0}-{1}", viewName, lineId)].Split(',');
- for (int i = 0; i < keys.Length; i++)
- {
- if (row[dts.PrimaryKey[i]].ToString() != keys[i].Substring(1, keys[i].Length - 2))
- {
- wouldUpdate = false;
- break;
- }
- }
- if (wouldUpdate)
- {
- switch (col.DataType.Name)
- {
- case "String":
- if (row[col].ToString() != Request.Params[param].ToString())
- {
- row[col] = Request.Params[param].ToString();
- }
- break;
- }
- updated = true;
- }
- if (updated)
- {
- break;
- }
- }
- }
- }
- }
- }
- DataTable updDataTable = dts.GetChanges();
- if (updDataTable != null)
- {
- SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(das);
- das.InsertCommand = cmdBuilder.GetInsertCommand();
- das.DeleteCommand = cmdBuilder.GetDeleteCommand();
- das.UpdateCommand = cmdBuilder.GetUpdateCommand();
- das.Update(updDataTable);
- cmdBuilder.Dispose();
- cmdBuilder = null;
- }
- SqlParameterCollection sqlParams = cmd.Parameters;
- foreach (XmlNode filterNode in xmlDefinition.SelectNodes("view/filters/filter" ))
- {
- if (filterNode.Attributes["name"].Value == filterName)
- {
- if (filterNode.Attributes["sql"] != null)
- {
- sql += " where " + filterNode.Attributes["sql"].Value;
- foreach (XmlNode parameterNode in filterNode.SelectNodes("parameter" ))
- {
- SqlParameter param = new SqlParameter();
- param.ParameterName = parameterNode.Attributes["name"].Value;
- param.Size = int.Parse(parameterNode.Attributes["length"].Value);
- param.Scale = byte.Parse(parameterNode.Attributes["scale"].Value);
- param.Precision = byte.Parse(parameterNode.Attributes["precision"].Value);
- switch (parameterNode.Attributes["sqltype"].Value)
- {
- case "nvarchar":
- param.SqlDbType = SqlDbType.NVarChar;
- param.Value = parameters[parameterNode.Attributes["name"].Value];
- sqlParams.Add(param);
- break;
- case "numeric":
- param.SqlDbType = SqlDbType.Decimal;
- param.Value = Int64.Parse(parameters[parameterNode.Attributes["name"].Value]);
- sqlParams.Add(param);
- break;
- }
- }
- }
- break;
- }
- }
- if (sortName != string.Empty)
- {
- foreach (XmlNode sortNode in xmlDefinition.SelectNodes("view/sorts/sort" ))
- {
- if (sortNode.Attributes["name"].Value == sortName)
- {
- sql += string.Format(" order by {0}", sortNode.Attributes["sql"].Value);
- break;
- }
- }
- }
- cmd.CommandText = sql;
- cmd.CommandType = CommandType.Text;
- cmd.Prepare();
- DataTable dt = new DataTable();
- SqlDataAdapter da = new SqlDataAdapter(cmd);
- da.Fill(dt);
- foreach (DataRow row in dt.Rows)
- {
- XmlNode rLine = outputNode.OwnerDocument.CreateElement("line" );
- // Create Primary Key definition
- XmlAttribute pk = rLine.OwnerDocument.CreateAttribute("primaryKey" );
- string pkVal = string.Empty;
- foreach (DataColumn dc in dts.PrimaryKey)
- {
- pkVal += string.Format("<{0}>,", row[dc.ColumnName].ToString());
- }
- if (pkVal != string.Empty)
- {
- pk.Value = pkVal.Substring(0, pkVal.Length - 1);
- }
- rLine.Attributes.Append(pk);
- foreach (DataColumn col in dt.Columns)
- {
- XmlElement rNode = rLine.OwnerDocument.CreateElement(col.ColumnName);
- rNode.InnerXml = row[col].ToString();
- XmlAttribute rAtt = rLine.OwnerDocument.CreateAttribute("type" );
- rAtt.Value = col.DataType.Name;
- rNode.Attributes.Append(rAtt);
- rLine.AppendChild(rNode);
- }
- outputNode.AppendChild(rLine);
- // For each row, we can have embeded views
- if (view.SelectNodes("views/view" ) != null)
- {
- RenderViews(outputNode, view.SelectNodes("views/view" ), row);
- }
- }
- dts.Dispose();
- das.Dispose();
- dt.Dispose();
- da.Dispose();
- cmd.Dispose();
- // Add data to output view node
- output.AppendChild(outputNode);
- // Free memory resources and files handles
- dts = null;
- das = null;
- dt = null;
- da = null;
- cmd = null;
- outputNode = null;
- xmlDefinition = null;
|
Message édité par Arjuna le 13-07-2006 à 14:27:23
|