循环与自定义类

本文关键字:自定义 循环 | 更新日期: 2023-09-27 18:26:19

我正在用两个"column-in(list)"样式的规则编写动态sql查询的where子句。

我可以在诸如LocationID/ProductID或TransactionID/FeeID之类的int ID对中多次看到这种情况。

以下示例不需要将类放置在方法外部,并从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 + ", "; 的循环

循环与自定义类

它们是不同的查询。第一种方法获得Xs的不同列表和Ys的不同列表。第二种方法是尝试获得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);
  }

使用第二种方法,您可以获得更好的性能,因为您只枚举了一次源列表,但除非这是一个严重的瓶颈,否则总体上可能不会有什么不同。

这取决于xy是否相关。

如果他们没有亲属关系,而你只是对他们做同样的事情,那么不要把他们归入一个类。如果适用的话,您可能会考虑将重复的代码放入一个方法中,但不要只是将两个随机值放入一个类中。

如果它们是相关的,比如它们是一个点的x和y坐标,那么你应该把它们放在一个类中来表示你的点。


在你的情况下,看起来你甚至不需要为他们创建一个新的类。他们已经排成一排了。

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

考虑到我最终使用代码的数量,以及使用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;
        }
    }
}

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