要写一个C#的api访问接口,get方式传参,需求:参数个数和参数名不固定。例如:
参数是 element,time,class,则后台实现 select element from tab1 where datatime>time and className=class;
如果传参数 element, time,class,order,则后台实现 select element from tab1 where datatime>time and className=class order by order;
还要类似很多这种情况, 怎么写一个通用的方法实现
你这个是针对sql脚本的,首先,你要针对这种形式写一个接收参数的class.
例:
public class searchClass{
public string display{get;set;}//多个参数可以用,形式,例 如:a,b,c,element
public string table{get;set;}
public List conditions{get;set;}
//可以加更多参
}
public class searchCondition{
public string key {get;set;}
public string value{get;set;}
public string fn{get;set;}// > < = ...
}
public IctionResult Api(searchClass param)
{
string sql = " select "+param.display+" from " + param.param ;
if(param.conditions!=null && param.conditions.count()>0)
sql+=" where 1=1 ";
foreach (var item in param.conditions) sql += " and " + item.key + item.fn + item.value;
if (o != null) sql += " order by" + o;
}
DataSet MyQuery(string tablename, string[] param, string[] op, string[] cond, string o)
{
string sql = " select element from " + tablename + " where 1=1 ";
foreach (var item in param.Zip(op, (x, y) => new { x, y }).Zip(cond, (x, z) => new { x.x, x.y, z }))
sql += " and " + item.x + item.y + item.z;
if (o != null) sql += " order by" + o;
...
}
element,time,class
MyQuery("element", new string[] { "datetime" }, new string[] { ">" }, new string[] { time }, null);
element, time,class,order
MyQuery("element", new string[] { "datetime", "className" }, new string[] { ">", "=" }, new string[] { time, class }, "order");
上面的有点错误,这样
DataSet MyQuery(string sel, string[] param, string[] op, string[] cond, string o)
{
string sql = " select " + sel + " from tab1 where 1=1 ";
foreach (var item in param.Zip(op, (x, y) => new { x, y }).Zip(cond, (x, z) => new { x.x, x.y, z }))
sql += " and " + item.x + item.y + item.z;
if (o != null) sql += " order by" + o;
...
}
参数名不固定的话怎么知道这个参数是用到select还是where或者是order?
应该是约定好参数名,参数个数可以不固定,如果没有上送,则这个参数不参与查询就行。
或者可以前后台约定一个参数前缀,带有select_ 前缀的用于select .
首先你要区分传进来的参数是查询字段,还是查询条件,还是排序啊、分组啊什么的,这个是前提。
其次我感觉你需要的是一个高级查询,你需要定义一个类来处理你的参数,我给你写个样例,你对照着看能不能实现你的目的
public class TestFilter
{
public string time;
public string time2;
public OPDate timeWhere;
public string classValue;
public OPString classWhere;
public string GetFilterString()
{
StringBuilder FilterString = new StringBuilder();
FilterString.Append(GetOPString("", timeWhere, time, time2, "and"));
FilterString.Append(GetOPString("", classWhere, classValue, "and"));
return FilterString.ToString();
}
public string GetOPString(string FieldString, OPString MyOPString, string MyString, string OPLG = "AND")
{
if (OPLG == "AND" || OPLG == "or")
{
switch (MyOPString)
{
case OPString.等于:
return OPLG + " " + FieldString + " = '" + MyString + "'";
case OPString.不等于:
return OPLG + " " + FieldString + " <> '" + MyString + "'";
case OPString.包含:
return OPLG + " " + FieldString + " like '%" + MyString + "%'";
case OPString.以之开头:
return OPLG + " " + FieldString + " like '" + MyString + "%'";
case OPString.以之结尾:
return OPLG + " " + FieldString + " like '%" + MyString + "'";
default:
return "";
}
}
else
{
return "";
}
}
public string GetOPString(string FieldString, OPDate MyOPString, string MyDate, string MyDate2, string OPLG = "AND")
{
if (OPLG == "AND" || OPLG == "or")
{
switch (MyOPString)
{
case OPDate.早于:
return OPLG + " " + FieldString + " <= '" + MyDate + "'";
case OPDate.晚于:
return OPLG + " " + FieldString + " >= '" + MyDate + "'";
case OPDate.等于:
return OPLG + " " + FieldString + " = '" + MyDate + "'";
case OPDate.两者之间:
return OPLG + " (" + FieldString + " >= '" + MyDate + "' and " + FieldString + " < '" + MyDate2 + "')";
default:
return "";
}
}
else
{
return "";
}
}
public enum OPString
{
无 = 1,
等于 = 2,
不等于 = 3,
包含 = 4,
以之开头 = 5,
以之结尾 = 6
}
public enum OPDate
{
无 = 1,
早于 = 2,
晚于 = 3,
等于 = 4,
两者之间 = 5
}
}
上面的代码我给你写了处理查询条件的东西,有多少字段你就写多少个对应的条件字段和值字段的属性就可以。使用的时候,你只要实例化这个类,通过判断你的参数有那些,给对应的条件字段赋值,然后调用那个GetFilterString方法,在这个方法里面去做各种筛选,就可以拼接你的sql了