我有一个数据表有2个字段,示例如下所示
Field A Field B
0100 0300
0800 1122
5000 6000
这些都代表范围,即0100-0300,我想选择(如果有的话)在其边界内具有输入范围的行,即如果输入范围是0820-0900,那么将从上表中选择第2行。
我的问题是,是否有任何有效的方法可以做到这一点,而不是逐一查看数据表,直到我找到匹配项?
两个部分都应在定义的范围内。
我必须执行这个过程serval千次并且查找集很小所以我将查找数据放在数据表中,并且现在想要查询datable而不是必须数千次调用数据库。这是一种正确的方法还是更好地调用服务器?
答案 0 :(得分:4)
如果您已经从数据库加载了数据表,那么您可以使用许多方法直接使用内存中已有的DataTable来过滤您的值。 (在这种情况下再没有意义再去数据库)
DataTable.Select方法非常简单
string test = "0820-0900";
string[] parts = test.Split('-');
DataRow[] rows = dt.Select("FieldA <= '" + parts[0] +
"' AND FieldB >= '" + parts[1] + "'");
foreach(DataRow r in rows)
Console.WriteLine(r.Field<string>("FieldA") + "-" + r.Field<string>("FieldB"));
LINQ方式
var result = dt.AsEnumerable()
.Where(x => string.Compare(x.Field<string>("FieldA"),parts[0]) <= 0 &&
string.Compare(x.Field<string>("FieldB"),parts[1]) >= 0).ToList();
但所有这些方法都有问题,因为字符串&#34; 1111&#34;字母顺序低于字符串&#34; 3&#34;,因此,如果您的字段中的数据具有可变的字符串长度,则需要在数据的开头和用于检查您的内容的字符串中添加零。数据表。这将使代码更复杂,并且在工作结束时很难维护和测试。
解决方案是将数据库字段更改为数字,然后您可以使用简单比较来提取所需范围内的值
string test = "0820-0900";
string[] parts = test.Split('-');
DataRow[] rows = dt.Select("FieldA <= " + Convert.ToInt32(parts[0]) +
" AND FieldB >= Convert.ToInt32(parts[1]));
foreach(DataRow r in rows)
Console.WriteLine(r.Field<string>("FieldA") + "-" + r.Field<string>("FieldB"));
如果你没有内存中的表,你可以用这样的代码直接查询数据库
string test = "0820-0900";
string[] parts = test.Split('-');
string cmdText = "select * from table where field <= @p1 AND FieldB >= @p2";
using(SqlConnection cn = new SqlConnection(....))
using(SqlCommand cmd = new SqlCommand(cmdText, cn))
{
cn.Open();
cmd.Parameters.AddWithValue("@p1", Convert.ToInt32(parts[0]));
cmd.Parameters.AddWithValue("@p2", Convert.ToInt32(parts[1]));
using(SqlDataReader r = cmd.ExecuteReader())
{
DataTable dt = new DataTable();
dt.Load(r);
}
}
答案 1 :(得分:1)
尝试以下方法之一:
1. DataRow[] result = table.Select("FieldA >= 100 AND FieldA<= 300");
2. // Create a DataView
DataView dv = new DataView(dt);
dv.RowFilter = "FieldA >= 100 AND AND FieldA<= 300";
// dv will now have filtered rows only and you can use it as source