循环与自定义类

时间:2015-12-10 20:56:04

标签: c# for-loop

我正在编写动态sql查询的where子句,其中包含两个'list in(list)'样式规则。

我可以看到这种情况会出现多次,例如LocationID / ProductID或TransactionID / FeeID。

以下示例不需要在方法外部放置类,并从WHERE条件中删除重复项:

  var x = (from DataRow row in expected.Rows
            select row.ItemArray[0]).Distinct().ToArray()
  var y = (from DataRow row in expected.Rows
            select row.ItemArray[1]).Distinct().ToArray();
  for (int i = 0; i < x.Length; i++)
  {
       com.Parameters.AddWithValue("@x" + i, int.Parse(TIDs[i].ToString()));
  }
  for (int i = 0; i < y.Length; i++)
  {
       com.Parameters.AddWithValue("@y" + i, int.Parse(ItemIDs[i].ToString()));
  }

是否优于此样本,重复性较低,还是有更好的选择?

  public class xy 
  {
    public int x;
    public int y;
  }
  var xy = (from DataRow row in expected.Rows
          select new xy()
          {
              x = int.Parse(row.ItemArray[0].ToString()),
              y = int.Parse(row.ItemArray[1].ToString())
          }).Distinct().ToArray();
  for (int i = 0; i < xy.Length; i++)
  {
    com.Parameters.AddWithValue("@x" + i, xy[i].x);
    com.Parameters.AddWithValue("@y" + i, xy[i].y);
  }

两者都需要querystring += "@x" + i + ", ";

的循环

3 个答案:

答案 0 :(得分:2)

他们是不同的查询。第一个获取X的明确列表和Y的不同列表。第二个是尝试以获取XY 组合的独特列表。但是,由于xy被定义为class而不是struct,因此您将拥有多个具有相同xy值的实例。

如果只关注不同的组合,则可以避免使用匿名类型来使用自定义类(并避免引用相等问题):

var xy = (from DataRow row in expected.Rows
          select new
          {
              x = int.Parse(row.ItemArray[0].ToString()),
              y = int.Parse(row.ItemArray[1].ToString())
          }).Distinct().ToArray();
  for (int i = 0; i < xy.Length; i++)
  {
    com.Parameters.AddWithValue("@x" + i, xy[i].x);
    com.Parameters.AddWithValue("@y" + i, xy[i].y);
  }

可能使用第二种方法获得更好的性能,因为你只是枚举了一次源列表,但除非这是一个重要的瓶颈,否则它可能不会产生任何影响。

答案 1 :(得分:1)

这取决于xy是否相关。

如果它们没有相关性,而你只是对它们做同样的事情,那么就不要把它们放到课堂上。如果适用,您可以考虑将重复的代码放入方法中,但不要只将两个随机值放入类中。

如果它们是相关的,例如它们是一个点的x和y坐标,那么你应该将它们放入一个类来表示你的观点。

在你的情况下,看起来你甚至可能不需要为它们创建一个新类。他们已经在一个阵列中。

var xy = (from DataRow row in expected.Rows
      select row).Distinct().ToArray();

答案 2 :(得分:0)

鉴于我最终使用代码的数量,以及使用in运算符的where子句的数量变化

class SqlInHelper
{
    public static string AddTags (DataColumn col)
    {
        string colName = col.ColumnName;
        string addStr = "";
        int distinct = (from DataRow row in col.Table.Rows
                   select row[colName]).Distinct().Count();
        for(int i=0;i<distinct;i++)
        {
            addStr += "@" + colName + i + ", ";
        }

        return addStr.Substring(0, addStr.Length - 2); // remove last ", "
    }

    public static void AddParams(SqlCommand query, DataColumn col, out bool bValid)
    {
        string colName = col.ColumnName;
        var vals = (from DataRow row in col.Table.Rows
                        select row[colName]).Distinct().ToArray();
        if (query.CommandText.Contains("@" + colName + (vals.Length - 1))) {
            for (int i = 0; i < vals.Length; i++)
            {
                query.Parameters.AddWithValue("@" + colName + i, Convert.ChangeType(vals[i], col.DataType));
            }
            bValid = true;
        } else {
            bValid = false;
        }

    }
}

从风格上来说,我认为这样可以减少代码重复次数,加快查询速度(在运算符中进行较少的比较),并且更容易理解。