【问题标题】:How to get Rid of Duplicate Keys in Dictionary C#如何摆脱字典 C# 中的重复键
【发布时间】:2015-06-17 00:09:51
【问题描述】:

我不断收到错误消息:已添加项目。在字典中键入:'@QueryID' 正在添加的键:'@QueryID'。我对此做了一些研究,它告诉我我正在将重复的键插入到字典对象中。 .Net 中的字典对象只能具有唯一键。我不知道如何摆脱重复的键。

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;
    }

【问题讨论】:

  • 为什么不测试字典中是否存在键 - 如果存在,要么不添加它,要么更新它,如果它不存在,添加值
  • 您在循环中无条件地调用此函数:Parameters.Add("@QueryID", row["QueryID"]);。在第二次迭代中,bound 会抛出异常。你怎么期望它不呢?您的意思是使用QueryParameters 而不是Parameters

标签: c# sql


【解决方案1】:

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

然后您将完全忽略“内部”哈希表。

我怀疑您想摆脱“外部”哈希表,而在添加参数和指定查询参数时只使用“内部”哈希表 (QueryParameters)。

顺便说一句:

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

【讨论】:

  • 我摆脱了“外部”的hastable,只拥有“内部”的。但是,它仍然给我同样的错误。在添加新的字典键值之前,我是否需要先清除()任何传入的“queryParamters”?
  • @user3882842:如果您仍然在每次迭代中创建一个新实例,那么您真的不应该收到该错误。您正在每次仍然创建一个新实例,对吗? (Hashtable QueryParameters = new Hashtable(); 行仍然需要在循环内。)
  • 谢谢大家!在你们的帮助下,我能够通过使用内部参数来解决问题。
【解决方案2】:

这里有一个错误:

Hashtable QueryParameters = new Hashtable();
Parameters.Add("@QueryID", row["QueryID"]);
DataTable QueryDetails = db.Query("...", Parameters);

您刚刚创建了一个新的哈希表 QueryParameters,但您根本没有使用它。相反,您将 QueryID 参数添加到 Parameters 哈希表,而不是 QueryParameters 哈希表。由于这行代码是针对每一行执行的,所以它会在第二次迭代时崩溃。

您可以通过使用 QueryParameters 而不是 Parameters(对于下一行和下一行)来解决此问题。或者,您可以完全删除 QueryParameters 对象,然后重用您的 Parameters 对象:

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

【讨论】:

    猜你喜欢
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    • 2021-04-30
    • 2016-03-09
    相关资源
    最近更新 更多