2015-06-16 20 views
0

我一直在得到错误:项目已被添加。键入词典:添加'@QueryID'键:'@QueryID'。我对此做了一些研究,它告诉我我将重复键插入字典对象。 .Net中的Dictionary对象只能有唯一的键。我不知道如何摆脱重复键。如何摆脱字典C中的重复键#

class Program 
{ 
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

    static void Main() 
    { 
     EMMADatabase db = new EMMADatabase(""); //set string to pass in based on App.config 


     try 
     { 
      Hashtable Parameters = new Hashtable(); 
      //Parameters.Add("@UserCredentials", UserCredentials); 

      DataTable result = db.Query("exec Metrics_ETL.dbo.uspDetermineQueriesToRunBasedOnSchedules", Parameters); 
      DataTable QueriesToRun = db.Query("select QueryID from Metrics_ETL.dbo.QueriesToRun", Parameters); 

      foreach(DataRow row in QueriesToRun.Rows) 
      { 
       Hashtable QueryParameters = new Hashtable(); 
       Parameters.Add("@QueryID", row["QueryID"]); 
       DataTable QueryDetails = db.Query("select QueryID, Query, ObjectID, DataSourceID, DatabaseName, ServerName, ServerType, UserName, Password from Metrics_ETL.dbo.Queries where QueryID = @QueryID", Parameters); 

       //log.Info(row["QueryID"]); 
       //Console.WriteLine(row["QueryID"]); 

       //create datasource - query datasource - get data into a datatable 

       //write datatable to csv with correct filename (OR maybe C# can write to Excel) 
      } 



     } 
     catch(Exception e) 
     { 
      Console.WriteLine("Error: " + e); 
     } 
     finally 
     { 
      Console.Read(); 
     } 
    } 

我觉得这是在添加@QueryID值,但不能肯定。我是编程的初学者,所以我非常喜欢这个。任何建议将不胜感激。

private DataTable QueryToDataTable(string QueryString, Hashtable Parameters) 
    { 
     DataTable dt = new DataTable(); 

     using (new Impersonator("svc-emma-admin", "1dc", "618MId}QM")) 
     { 
      SqlCommand cmd = new SqlCommand(QueryString, DBConnection); 
      cmd.CommandTimeout = 120; 

      foreach (DictionaryEntry Parameter in Parameters) 
      { 
       cmd.Parameters.Add((string)Parameter.Key, SqlDbType.NVarChar); 
       cmd.Parameters[(string)Parameter.Key].Value = Parameter.Value; 
      } 

      SqlDataAdapter da = new SqlDataAdapter(cmd); 
      da.Fill(dt); 
     } 

     return dt; 
    } 
+0

为什么不测试字典中是否存在密钥 - 如果存在,请不要添加它,要么更新它,如果它不存在,请添加值 – Alex

+0

在你的循环中无条件地调用*:Parameters.Add(“@ QueryID”,row [“QueryID”]);'。在第二次迭代中,这是* bound *以引发异常。你是怎么指望它不?你的意思是使用'QueryParameters'而不是'Parameters'? –

回答

3

你在每个迭代上你的循环创造了单个Hashtable你的外循环,然后一个。但是,您无条件地在循环中添加单个“外部”哈希表,因此在第二次迭代中它肯定会失败。

然后你完全忽略了“内部”散列表。

我怀疑你希望摆脱“外部”散列表,并且只需使用“内部”散列表(QueryParameters)即可同时添加参数和指定查询参数。

顺便说一句:

  • 我会强烈建议使用泛型集合 - 在这种情况下可能是一个Dictionary<string, object>。非通用集合是如此2004.
  • 参数和局部变量通常是camelCased,例如, queryParameters,而不是QueryParameters
  • 您目前有一个“N + 1选择”问题 - 如果可能的话,您应该尝试使用连接一次执行整个查询。
+0

我摆脱了“外在”可憎的,只有“内在”一个。但是,它仍然给我同样的错误。在添加新字典键值之前,是否需要首先清除()任何传入“queryParamters”的内容? – BIDevLe

+0

@ user3882842:如果您仍然在每次迭代中创建一个新实例,则确实不应该出现该错误。你*还*每次都在创建一个新的实例,对吧?('Hashtable QueryParameters = new Hashtable();'行仍然需要在循环中。) –

+0

谢谢大家!在你们的帮助下,我能够通过使用内部参数来解决问题。 – BIDevLe

1

你有一个错误的位置:

​​

您刚刚创建了一个新的哈希表,QueryParameters,但你不使用它。而是将QueryID参数添加到参数散列表,而不是QueryParameters散列表。由于这行代码对每一行执行都会在第二次迭代时崩溃。

您可以通过使用QueryParameters而不是参数(对于下一行以及下一行)来解决问题。或者,你可以删除QueryParameters对象彻底和公正的重用你的参数object:

// Hashtable QueryParameters = new Hashtable(); 
Parameters.Clear(); 
Parameters.Add("@QueryID", row["QueryID"]);