Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
CommandBehavior.SchemaOnly
Message
 
 
À
30/07/2013 14:32:00
Information générale
Forum:
ASP.NET
Catégorie:
Code, syntaxe and commandes
Versions des environnements
Environment:
C# 4.0
OS:
Windows 7
Network:
Windows 2003 Server
Database:
MS SQL Server
Application:
Web
Divers
Thread ID:
01579375
Message ID:
01579473
Vues:
38
>>>A Dictionary should give close to O(1) look up time, whereas an IEnumerable will be O(n). Depending on the size of the list and how often its used, the speed difference is probably negligible. It is easy enough to create the Dictionary though:
>>>
Dictionary<string, ColumnSchema> columnTypes;
>>>
>>>            using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly))
>>>            {
>>>
>>>                 columnTypes = (from DataRow r in reader.GetSchemaTable().AsEnumerable()
>>>                                                  select new ColumnSchema
>>>                                                      {
>>>                                                          ColumnName = (string) r["ColumnName"],
>>>                                                          ColumnSize = (Int32) r["ColumnSize"],
>>>                                                          DbType = (SqlDbType) r["ProviderType"],
>>>                                                          DataType = (Type) r["DataType"]
>>>                                                      }).ToDictionary(cs=> cs.ColumnName);
>>>            }
>>
>>I made this change, but as far as I can tell, the speed I was getting last night using iteration by each row remained the same. E.g. the whole complex procedure I am testing takes about ~ 800ms.It's about 3 times quicker than VFP version.
>>
>>I guess there may be other places for optimization here.
>>
>>That's my current code for the reference:
>>
>>
>>/// <summary>
>>      /// Adds table schema to the tableSchema dictionary of all tables schemas
>>      /// </summary>
>>      /// <param name="tableName"></param>
>>      /// <param name="returnMessage"></param>
>>      private void AddTableSchema(String tableName, ref String returnMessage)
>>      {
>>         Logging.LogFormat(3, "Info: Did not find key value for '{0}' in schema dictionary ... Adding now...", tableName);
>>
>>         Dictionary<String, ColumnSchema> columnTypes = new Dictionary<String, ColumnSchema>(StringComparer.OrdinalIgnoreCase);
>>         String commandText = String.Format("select * from dbo.{0} where 0 = 1;", tableName);
>>         SqlConnection siriusSqlConnection = this.sqlConnection;
>>         if (null == siriusSqlConnection)
>>            return;
>>
>>         using (SqlCommand command = new SqlCommand(commandText, siriusSqlConnection))
>>         {
>>            try
>>            {
>>               Dictionary<String, ColumnSchema> columns; 
>>
>>               using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly))
>>               {
>>                  columns = (from DataRow r in reader.GetSchemaTable().AsEnumerable()
>>                             select new ColumnSchema
>>                             {
>>                                ColumnName = r["ColumnName"].ToString(),
>>                                DataType = reader.GetFieldType((int)r["ColumnOrdinal"]),
>>                                DbType = (SqlDbType)(Convert.ToInt32(r["ProviderType"])),
>>                                Precision = Convert.ToInt16(r["NumericPrecision"]),
>>                                Scale = Convert.ToInt16(r["NumericScale"]),
>>                                IsIdentity = r.Field<Boolean>("IsIdentity")
>>                             }).ToDictionary(cs => cs.ColumnName);
>>                  ////DataTable tbl = reader.GetSchemaTable();
>>                  //foreach (DataRow r in tbl.Rows)
>>                  //{                   
>>
>>                  //   colSchema.ColumnName = r["ColumnName"].ToString();
>>                  //   colSchema.ColumnSize = Convert.ToInt32(r["ColumnSize"]);
>>                  //   colSchema.DataType = sqlDataReader.GetFieldType((int)r["ColumnOrdinal"]);
>>                  //   colSchema.DbType = (SqlDbType)(Convert.ToInt32(r["ProviderType"]));
>>                  //   colSchema.Precision = Convert.ToInt16(r["NumericPrecision"]);
>>                  //   colSchema.Scale =  Convert.ToInt16(r["NumericScale"]);
>>                  //   colSchema.IsIdentity = r.Field<Boolean>("IsIdentity");
>>                  //   columnTypes.Add(colSchema.ColumnName, colSchema);
>>                  //}
>>                  
>>                  tableSchema.Add(tableName, new TableSchema(tableName, columns));                 
>>               }
>>            }
>>            catch (Exception ex)
>>            {
>>               returnMessage = ex.ToString();
>>            }
>>         }
>>      }
>
>Going from an iterative approach to an equivalent LINQ approach is rarely going to improve speed, and it may even slow it down due to the overhead involved. It does however allow you to easily make it parallel by adding an AsParallel() after AsEnumerable(), which may improve the speed. I don't know if the data reader's GetFieldType method is thread-safe, so that may not be an option. You could also use the appropriate .Field< Type> instead of Convert if they are already the correct type.
>
>Of course you'll need to test if the LINQ statement is actually the slow part of your code.

I don't think it's the LINQ part that is slow. The procedure itself is rather complex and uses many methods. I am wondering what is the best way to see which portions of the code are slowest and may need improvements?

Also, in regards to Field < Type > comment - I can not find documentation as what is the type of each property. Do you know how to figure this out? - Never mind this question, I used GetType to find out type of each column in returned info.
If it's not broken, fix it until it is.


My Blog
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform