循环与自定义类
本文关键字:自定义 循环 | 更新日期: 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 + ", ";
的循环
它们是不同的查询。第一种方法获得X
s的不同列表和Y
s的不同列表。第二种方法是尝试获得X
和Y
组合的不同列表。但是,由于xy
被定义为class
而不是struct
,您将有多个具有相同值x
和y
的实例。
如果只获得不同的组合不是一个问题,那么可以通过使用匿名类型来避免使用自定义类(并避免引用相等问题)
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);
}
使用第二种方法,您可以获得更好的性能,因为您只枚举了一次源列表,但除非这是一个严重的瓶颈,否则总体上可能不会有什么不同。
这取决于x
和y
是否相关。
如果他们没有亲属关系,而你只是对他们做同样的事情,那么不要把他们归入一个类。如果适用的话,您可能会考虑将重复的代码放入一个方法中,但不要只是将两个随机值放入一个类中。
如果它们是相关的,比如它们是一个点的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运算符可以进行较少的比较),并且更容易理解。