C# 添加列会添加数千个空行

C# 添加列会添加数千个空行,c#,sql-server,C#,Sql Server,我有一个返回161行的sql语句。当我添加一个额外的列(不是键)时,返回的行数增加到5000多行,其中绝大多数都是空的 sql语句应该获取一个客户的配置列表,并显示来自另一个客户的所有匹配配置(“匹配”表示具有相同的配置名称)。我需要查看它是否匹配,还需要有那些不匹配的配置数据 我的代码: ... var myTable = new DataTable(); try { string sql = "SELECT SourceConfig.Configur

我有一个返回161行的sql语句。当我添加一个额外的列(不是键)时,返回的行数增加到5000多行,其中绝大多数都是空的

sql语句应该获取一个客户的配置列表,并显示来自另一个客户的所有匹配配置(“匹配”表示具有相同的配置名称)。我需要查看它是否匹配,还需要有那些不匹配的配置数据

我的代码:

...

    var myTable = new DataTable();
    try
    {
        string sql = "SELECT SourceConfig.ConfigurationId AS 'SourceID', " +
                            "SourceConfig.Name, " +
    /* Added this line */   "SourceConfig.ConfigurationData AS 'SourceData', " +
                            "TargetConfig.ConfigurationId AS 'TargetID' " +
                     "FROM ConfigurationTable SourceConfig " +
                     "LEFT JOIN ConfigurationTable TargetConfig ON " +
                         "(TargetConfig.CustomerID = " + getTargetID() + " AND " +
                         "SourceConfig.Name = TargetConfig.Name)" +
                     "WHERE SourceConfig.CustomerId = " + getSourceID();
        myTable = this.accessService.FetchDataFromCustomerDatabase(sql);
        myTable.PrimaryKey = new DataColumn[1] { myTable.Columns[0] }; // Error here
    }
    catch (Exception e)
    {
        // Record error message
        return;
    }

    // Do stuff with 'myTable'
...
我以前的代码没有sql语句的第三行引入“ConfigurationData”,但为什么添加该行会导致此错误?“ConfigurationData”列不是键、主键或其他键。我尝试添加另一个WHERE条件来排除空值,但仍然得到数千行

真正重要的是,当我在“Microsoft SQL Management Studio”中运行相同的SQL语句时,不会发生此错误。在那里,我仍然得到161行返回;只有当我在VisualStudio中运行我的c#代码时,我才会被这些空行轰炸


我认为问题与新列的数据类型有关,SQL Management Studio将其标记为“(XML(.),NOTNULL)”。我尝试过添加其他列,而不是“ConfigurationData”,只是其中一列会像这样爆炸。

因此,在试图保护自己不受SQL注入的影响时,我最终解决了最初的问题。想想看。我从这里找到了解决方案:

本质上,问题在于“FetchDataFromCustomerDatabase()”,如果我以安全的方式做事,我不会使用该方法。新守则:

...

    var myTable = new DataTable();
    try
    {
        using (SqlConnection connection = new SqlConnection(ConnectionString))
        {
            string sql = "SELECT SourceConfig.ConfigurationId AS 'SourceID', " +
                                "SourceConfig.Name, " +
                                "SourceConfig.ConfigurationData AS 'SourceData', " +
                                "TargetConfig.ConfigurationId AS 'TargetID' " +
                         "FROM ConfigurationTable SourceConfig " +
                         "LEFT JOIN ConfigurationTable TargetConfig ON " +
                             "(TargetConfig.CustomerID = @targetCustID AND " +
                             "SourceConfig.Name = TargetConfig.Name)" +
                         "WHERE SourceConfig.CustomerId = @sourceCustID";

            var command = new SqlCommand(sql, connection);
            command.Parameters.Add("@sourceCustID", SqlDbType.Int);
            command.Parameters.Add("@targetCustID", SqlDbType.Int);
            command.Parameters["@sourceCustID"].Value = sourceCustID;
            command.Parameters["@targetCustID"].Value = targetCustID;

            var da = new SqlDataAdapter(command);
            da.Fill(myTable);
            da.Dispose();

            myTable.PrimaryKey = new DataColumn[1] { myTable.Columns[0] };
        }
    }
    catch (Exception e)
    {
        // Record error message
        return;
    }

    // Do stuff with 'myTable'
...

您的代码易受SQL注入的影响。您应该使用参数。如果怀疑数据层有问题,请调查数据层。打开一个黑盒子,它是
从CustomerDatabase()获取数据。
。打开这个盒子的想法让我很震惊,但如果这是唯一的方法。。。另外,关于SQL注入的一点很好,我可能不应该把它留到以后。