在我的场景中,我必须根据用户在屏幕上选择的内容构建动态查询。
用户可以选择列名,然后选择运算符,然后键入值。
我已经为平等而做了,但是LIKE和NOT LIKE的语法怎么样? 所以
第一。我将列名添加到我的列表中
var columns = new Dictionary<string, string>
{
{"CurrentStatus", "Current Status"},
{"RequestNumber", "Request Number"},
{"RequestDate", "Request Date"},
{"IsOnHold", "Is On Hold"},
{"BrandReturnedVehicle", "Brand Returned Vehicle"},
{"TypeReturnedVehicle", "Type Returned Vehicle"},
{"ChassisReturnedVehicle", "Chassis Returned Vehicle"},
{"DestructionCertificateNumberReturnedVehicle",
"Destruction Certificate Number Returned Vehicle"},
{"AmmountWithVAT", "Ammount WithVAT "},
{"AmmountWithoutVat", "Ammount Without Vat"},
{"Percentage", "Percentage"},
{"VehicleDestructionDate", "Vehicle Destruction Date"},
{"Comments", "Comments"},
{"Discriminator", "Request Type"},
};
DdlColumn1.DataSource = columns;
DdlColumn1.DataTextField = "Value";
DdlColumn1.DataValueField = "Key";
DdlColumn1.DataBind();
第二。根据所选的列名称,我将运算符添加到下拉列表中。
protected void DdlColumn1SelectedIndexChanged(object sender, EventArgs e)
{
LoadOperatorsDependingOnColumn(sender as DropDownList, DdlColumn1.SelectedValue);
}
private void LoadOperatorsDependingOnColumn(DropDownList ddlOperators, string columnname)
{
var operators = new Dictionary<string, string>();
operators.Clear();
switch (columnname)
{
case "CurrentStatus":
AddTextOperatorsToList(operators);
ddlOperators.DataSource = operators;
ddlOperators.DataTextField = "Value";
ddlOperators.DataValueField = "Key";
ddlOperators.DataBind();
break;
case "AmmountWithVat":
AddNumberOperatorsToList(operators);
break;
}
}
private static void AddTextOperatorsToList(Dictionary<string, string> operators)
{
operators.Add("==", "Equals");
operators.Add("<>", "Not Equals");
operators.Add("LIKE", "Contains");
operators.Add("NOT LIKE", "Does not Contain");
}
private static void AddNumberOperatorsToList(Dictionary<string, string> operators)
{
operators.Add("=", "Equals");
operators.Add("<>", "Not Equals");
operators.Add(">", "Greater than");
operators.Add(">=", "Greater or equal than");
operators.Add("<", "Less than");
operators.Add("<=", "Less or equal than");
}
private string ColumnType(string columnName)
{
switch (columnName)
{
case "CurrentStatus":
return "Text";
break;
case "RequestNumber":
return "Text";
break;
}
}
private string BuildQuery()
{
var sb = new StringBuilder();
//var list = RequestBaseBL.GetRequestByCustomQuery("RequestNumber == \"12\"");
if (ColumnType(DdlColumn1.SelectedValue) == "Text" && DdlOperator1.SelectedItem.Text=="==")
{
sb.Append(DdlColumn1.SelectedValue);
sb.Append(DdlOperator1.SelectedValue);
sb.Append("\"" + TxtValue1.Text + "\"");
}
答案 0 :(得分:2)
似乎动态linq的东西不支持'LIKE' - 但我想这就是你问这个问题的原因。我能想到的最好的方法是用类似(x> = y0和x&lt; y1)的方式替换LIKE。
所以:
if (ColumnType(DdlColumn1.SelectedValue) == "Text" && DdlOperator1.SelectedItem.Text=="LIKE")
{
string s = TxtValue1.Text;
Char c = s[s.Length - 1];
string s1 = s.Substring(0, s.Length - 1) + ((Char)(c + 1));
string clause = string.Format("{0} >= \"{1}\" and {0} < \"{2}\"", DdlColumn1.SelectedValue, s, s1);
sb.Append(clause);
}
即将1添加到搜索字符串的最后一个字符的值中,并将其用作搜索的上限 如果你知道你只处理简单的拉丁字符,你可以使它更简单并使用:
string clause = string.Format("{0} >= \"{1}\" and {0} <= \"{1}z\"", DdlColumn1.SelectedValue, TxtValue1.Text);
但值得一看predicate builder here以获得更多类型安全性。
修改
嗯,我从来没有!忘记这一切。
似乎你可以使用“myField.Contains(myCriteria)”和“myField.StartsWith(myCriteria)”进行CONTAINS和LIKE
sb.Append(string.Format("{0}.Contains(\"{1}\")", DdlColumn1.SelectedValue, TxtValue1.Text);
和
sb.Append(string.Format("{0}.StartsWith(\"{1}\")", DdlColumn1.SelectedValue, TxtValue1.Text);
并且,对于NOT LIKE:
sb.Append(string.Format("!{0}.StartsWith(\"{1}\")", DdlColumn1.SelectedValue, TxtValue1.Text);