我正在编写动态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 + ", ";
答案 0 :(得分:2)
他们是不同的查询。第一个获取X
的明确列表和Y
的不同列表。第二个是尝试以获取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);
}
你可能使用第二种方法获得更好的性能,因为你只是枚举了一次源列表,但除非这是一个重要的瓶颈,否则它可能不会产生任何影响。
答案 1 :(得分:1)
这取决于x
和y
是否相关。
如果它们没有相关性,而你只是对它们做同样的事情,那么就不要把它们放到课堂上。如果适用,您可以考虑将重复的代码放入方法中,但不要只将两个随机值放入类中。
如果它们是相关的,例如它们是一个点的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;
}
}
}
从风格上来说,我认为这样可以减少代码重复次数,加快查询速度(在运算符中进行较少的比较),并且更容易理解。