【问题标题】:Why is the 'if' condition in my while loop only checked once?为什么我的while循环中的'if'条件只检查一次?
【发布时间】:2015-05-03 16:08:27
【问题描述】:

我已经编写了代码来阻止我的主键重复。我有两张桌子。一个表保存公司详细信息,另一个表保存其他详细信息。在保存公司详细信息的表格中,公司注册号作为主键给出。它不应该被复制。但是注册号是另一个表的外键,可以随意复制。

这是我的代码:

public int checkComRegnumberAvailable(string conRegnumber)
{   
    int check = 2;
    int i = 0;

    List<OtherCompany> checklist = getCompanyDetails();

    while (i < checklist.Count)
    { 
        if (checklist[i].RegNumber != conRegnumber)
        {
            check = 0;
            i++;
        }

        else
        {
            check = 1;
            i++;
        }
    }

    return check; 
}

下面是我根据整数check的值执行SQL语句的method:

public void AddCompanyDetails(int NDAid)
{
    using (SqlConnection con = new SqlConnection(cs))
    {
        int check = checkComRegnumberAvailable(oc.RegNumber);

        if (check == 0)
        {
            SqlCommand cmd = new SqlCommand("INSERT INTO OtherCompanyData (RegNumber,ComName,Country,Address,CoreBusi) values (@regnum,@comname,@country,@address,@corebusi) ", con);

            cmd.Parameters.AddWithValue("@regnum", oc.RegNumber);
            cmd.Parameters.AddWithValue("@comname", oc.ComName);
            cmd.Parameters.AddWithValue("@country", oc.Country);
            cmd.Parameters.AddWithValue("@address", oc.RegOfficeAddress);
            cmd.Parameters.AddWithValue("@corebusi", oc.CoreBuss);

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                AddNDADetails(NDAid);
            }

            catch (SqlException ex)
            {
                throw ex;
            }
        }

        else if (check == 1)
        {
            AddNDADetails(NDAid);
        }
    }
}

在执行代码时出现以下异常:

请帮助我。提前致谢。

【问题讨论】:

  • 如果调用相同的 add 函数,检查的意义何在?
  • 你怎么知道它只检查了一次?顺便说一句,这是没有意义的,因为您只返回最后一项条件的结果
  • @chouaib 我插入了一个断点来检查迭代。
  • hein... i 增加了,还是在第一次迭代后离开了循环? (我相信不会)

标签: c# asp.net while-loop sqlexception


【解决方案1】:

代码有很多地方需要重新考虑。

首先,您只能从结果中的 getCompanyDetails() 获取 LAST 元素。另外,当你应该返回一个布尔值时,你为什么要返回一个 int 值?仅当数组为空时才会返回 2,并且您甚至没有捕捉到该条件。

第一次改进:

public int checkComRegnumberAvailable(string conRegnumber)
{       
    List<OtherCompany> checklist = getCompanyDetails();

    foreach (var listItem in checklist)
    { 
        if (listItem.RegNumber == conRegnumber)
        {
            return 1;
        }
    }

    return 0; 
}

更好:

public bool checkComRegnumberAvailable(string conRegnumber)
{   
    return !getCompanyDetails().Any(cd => cd.RegNumber.Equals(conRegnumber));       
}

你的第二种方法应该是:

public void AddCompanyDetails(int NDAid)
{
    if (checkComRegnumberAvailable(oc.RegNumber))
    {
        using (SqlConnection con = new SqlConnection(cs))
        {             
            SqlCommand cmd = new SqlCommand("INSERT INTO OtherCompanyData (RegNumber,ComName,Country,Address,CoreBusi) values (@regnum,@comname,@country,@address,@corebusi) ", con);

            cmd.Parameters.AddWithValue("@regnum", oc.RegNumber);
            cmd.Parameters.AddWithValue("@comname", oc.ComName);
            cmd.Parameters.AddWithValue("@country", oc.Country);
            cmd.Parameters.AddWithValue("@address", oc.RegOfficeAddress);
            cmd.Parameters.AddWithValue("@corebusi", oc.CoreBuss);

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
            }

            catch (SqlException ex)
            {
                throw ex;
            }
        }
    }

    AddNDADetails(NDAid);        
}

【讨论】:

    【解决方案2】:

    您拥有的代码检查每一行并根据该行将check 设置为零或一。

    这意味着check 将在循环退出时仅根据最后行设置。

    需要将其更改为类似的内容,假设如果列表为空则需要两个,如果找到则需要一个,如果没有找到则为零(从您当前的代码看来就是这种情况(a)支持>):

    public int checkComRegnumberAvailable (string conRegnumber) {   
        List<OtherCompany> checklist = getCompanyDetails();
        if (checklist.Count == 0)
            return 2;
    
        for (int i = 0; i < checkList.Count; i++)
            if (checklist[i].RegNumber == conRegnumber)
                return 1;
    
        return 0;
    }
    

    (a) 这里需要小心,因为调用函数AddCompanyDetails 确实不考虑了一个空列表。如果您希望将空列表视为与“记录不存在”相同(可能应该如此),请删除返回 2 的 if 块。

    【讨论】:

      【解决方案3】:

      您希望您的代码在添加之前找出是否存在重复项,但您真正要做的只是验证最后一个元素是否不匹配。

      相反,这样做:

      public int checkComRegnumberAvailable(string conRegnumber)
      {   
          int i = 0;
      
          List<OtherCompany> checklist = getCompanyDetails();
          foreach(var company in checklist)
          {
              if(company.RegNumber == conRegnumber)
              { 
                  return 1;
              }
          }
      
          return 0;
      }
      

      有更好的方法来完成你正在做的事情,但这应该证明你当前逻辑中的问题。

      【讨论】:

      • 你怎么能说OP只检查最后一个元素?
      • 他的代码,如所写,如果最后一个元素匹配,则返回 1,否则返回 0。中间元素的值没有影响。
      • 非常感谢。干杯!
      猜你喜欢
      • 2022-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-03
      • 2016-08-21
      • 2015-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多