public string getSearchResult(string qry, string options, string noOfRecords, string strrefine)
{
string Query = "";
if (qry == "") return "";
string[] qrymod = qry.Split(' ');
if (qrymod.Length > 1)
{
for (int i=1; qrymod.Length > i; i++)
{
qry =qrymod[i];
}
}
//qry = qrymod[0];
qry = qry.Replace("\\", "\\\\").Replace("%", "\\%").Replace("_", "\\_");
if (options == "A" || options == "AC")
Query += " Select top " + noOfRecords + " cast(activityid as nvarchar(50)) as 'id',title as 'title',cast(description as varchar(200)) as 'desc' ,'AC' as 'Type' from searchActivity WHERE title like '%" + chkText(qry) + "%' or description like '%" + chkText(qry) + "%' escape '\\' ";
}
I can perform search from this function but the issue is whenever i am entering the text with two words
it searches the word after entering space the function will start searching the 2nd word
i want to compile the search result to search both the words
You want to do a full text query... Have a look here
Related
I'm working on a simple translation application based on C# & SQL Server CE 3.5
I have a search textbox that searches certain columns in database through textBox1.Text with normal SQL query [SELECT.. LIKE '% %']
What I want to achieve :
I want to search for all the words after certain symbols (+ for example) in all locations in database , so they don't need to be written in the full context (word after word as they exist in database)
In other words :
I want to split words after certain symbols , so that the program search for each word independently (search the word before symbol and each word after symbol separately)
Example:
If I tried to search for the value "burden of proof" , I've to write it in the previous context, but for the user this will not apply. So I want him to put a symbol in-between the two words he is willing to search for (namely he should search for "burden+proof")
Picture 1 : http://i.imgur.com/sd5Y5B7.jpg , Picture 2 : http://i.imgur.com/gVj41xP.jpg
Edit - my search button code :
sqlcmd = new SqlCeCommand
("SELECT * FROM T1 WHERE EnglishWord like '%" + textBox1.Text + "%' OR EnglishDesc like '%" + textBox1.Text + "%' OR ArabicWord like '%" + textBox1.Text + "%' OR ArabicDesc like '%" + textBox1.Text + "%' ", sqlcon);
try
{
listView1.Items.Clear();
sqldr = sqlcmd.ExecuteReader();
while (sqldr.Read())
{
ListViewItem item = new ListViewItem(sqldr["ID"].ToString());
item.SubItems.Add(sqldr["EnglishWord"].ToString());
item.SubItems.Add(sqldr["EnglishDesc"].ToString());
item.SubItems.Add(sqldr["ArabicDesc"].ToString());
item.SubItems.Add(sqldr["ArabicWord"].ToString());
item.SubItems.Add(sqldr["Subject"].ToString());
listView1.Items.Add(item);
}
listView1.Enabled = true;
label7.Text = listView1.Items.Count.ToString();
}
catch (SqlCeException ex)
{
MessageBox.Show("Error: " + ex.Message, "Something wrong");
}
Ok. So you got different words from the answer here.
Split textbox.text into other textboxes
You have this string[] result that you know if the length is 1 than it didnt split at all. If it is more than 1 than the original text was split with + or whatever.
I am not sure exactly what you are trying to achieve but you could do this.
if(result.Length == 1)
{
//Select * from database where column = result[0]
}
else
{
foreach(string s in result)
{
//Select * from database where column like '%'+s+'%' (better if you do with parameters)
}
}
Answer by : Richard Deeming # CodeProject
Assuming you want to find all records where each word appears in at least one of the four columns, something like this should work:
sqlcmd = sqlcon.CreateCommand();
string[] words = textBox1.Text.Split(new[] { '+' }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder query = new StringBuilder("SELECT * FROM T1 WHERE 1 = 1");
for (int index = 0; index < words.Length; index++)
{
string wordToFind = words[index];
string parameterName = "#word" + index;
sqlcmd.Parameters.AddWithValue(parameterName, "%" + wordToFind + "%");
query.AppendFormat(" AND (EnglishWord Like {0} OR EnglishDesc Like {0} OR ArabicWord Like {0} OR ArabicDesc Like {0})", parameterName);
}
sqlcmd.CommandText = query.ToString();
This will also fix the SQL Injection[^] vulnerability in your code.
If the user searches for burden+proof, the resulting query will look something like this:
SELECT
*
FROM
T1
WHERE
1 = 1
And
(
EnglishWord Like #word0
Or
EnglishDesc Like #word0
Or
ArabicWord Like #word0
Or
ArabicDesc Like #word0
)
And
(
EnglishWord Like #word1
Or
EnglishDesc Like #word1
Or
ArabicWord Like #word1
Or
ArabicDesc Like #word1
)
/*
Parameters:
- #word0 = '%burden%'
- #word1 = '%proof%'
*/
I want to dynamically build the lambda expression so that I can build a query with an unknown number of fields...how do I accomplish this?
I am looping through an object that contains all of the fields and values adding to the Where clause for each field...
searcher = searcher.Where(f => f.fieldName.Contains(fieldValue));
i.e. pseudo-code:
foreach(var field in fields){
searcher = searcher.Where(f => field.name.Contains(field.value));
}
If I were living in the stone-age I'd pseudo-code it like this:
var first = true;
string query = " SELECT * FROM TABLE WHERE ";
foreach(var field in fields){
if(first){
query += field.name + " LIKE '%" + field.value + "%' ";
}else{
query += " AND " + field.name + " LIKE '%" + field.value + "%' ";
}
first = false;
}
Please tell me the stone-age isn't more powerful than current technology! ;-)
I hope this will be helpful.
searcher = fields.Aggregate(searcher, (current, field) => current.Where(f => f.Name.Contains(f.Value)));
I have a registration application for a Windows Surface Tablet PC.
It works brilliantly but there's one more thing i need to work:
The registration works by either being in an Online State(For a Staff Register), or an Offline State(For Student Event Registrations).
When it's in its Online State, we scan barcodes in to it which holds 6 digits + 'L' , which goes to the database and pulls out the Staff Members name and 6 digit code, then it will list the Staff Members name in order down the listbox.
What i am looking to do is List the time it was first entered into the application, and then when they scan the same code again, instead of removing the first entry it will add another time onto the existing line, such as:
First Scan:
Ryan Gillooly (123456) Time: 11:40
Second Scan:
Ryan Gillooly (123456) Time: 11:40 Time: 13:26
and so on and so forth.
Here is the code :
Object returnValue;
string txtend = textBox1.Text;
if (e.KeyChar == 'L')
{
DBConnection.Open();
}
if (DBConnection.State == ConnectionState.Open)
{
if (textBox1.Text.Length != 6) return;
{
cmd.CommandText = ("SELECT last_name +', '+ first_name from name where id =#Name");
cmd.Parameters.Add(new SqlParameter("Name", textBox1.Text.Replace(#"L", "")));
cmd.CommandType = CommandType.Text;
cmd.Connection = DBConnection;
returnValue = cmd.ExecuteScalar() + "\t (" + textBox1.Text.Replace(#"L", "") + ")";
DBConnection.Close();
if (listBox1.Items.Contains(returnValue))
{
for (int n = listBox1.Items.Count - 1; n >= 0; --n)
{
string removelistitem = returnValue.ToString();
if (listBox1.Items[n].ToString().Contains(removelistitem))
{
//listBox1.Items.Add(" " + "\t Time:" + " " + DateTime.Now.ToString("HH.mm"));
listBox1.Items.RemoveAt(n);
}
}
}
else
listBox1.Items.Add(returnValue + "\t Time:" + " " + DateTime.Now.ToString("HH.mm"));
textBox1.Clear();
System.IO.StreamWriter SaveFile = new System.IO.StreamWriter(fullFileName);
foreach (object item in listBox1.Items)
SaveFile.WriteLine(item.ToString());
SaveFile.Flush();
SaveFile.Close();
if (listBox1.Items.Count != 0) { DisableCloseButton(); }
else
{
EnableCloseButton();
}
Current_Attendance_Label.Text = "Currently " + listBox1.Items.Count.ToString() + " in attendance.";
e.Handled = true;
}
}
Try something like this:
.....
DBConnection.Close();
bool found=false;
foreach (var item in listBox1.Items)
{
var entry = item.ToString();
if (entry.Contains(returnvalue.ToString()))
{
listBox1.Items.Remove(item);
listBox1.Items.Add(entry + " extra add");
found = true;
break;
}
}
if (!found)
{
listBox1.Items.Add(returnvalue.ToString());
}
textBox1.Clear();
.....
UPDATE
Regarding your extra question in the comments:
You could use string.LastIndexOf to see which word was added last: "In" or "Out".
And then you take the other.
LastIndexOf returns the index of the last occurence of the searchstring, or -1 when it's not present.
Out of my mind you would get something like:
private string CreateNewEntry(string current)
{
var indexIn = current.LastIndexOf("in"); // Get the last index of the word "in"
var indexOut = current.LastIndexOf("out"); // Get the last index of the word out
if (indexOut > indexIn)
{
return current + " in "; // if the last "out" comes after the last "in"
}
else
{
// If the last "in" comes after the last "out"
return current + " out ";
}
}
This will return the current entry + " in " or " out ".
Anbd then you just have to add your extra stuff to it.
To call this, replace the Add-sentences with:
listBox1.Items.Add(CreateNewEntry(entry) + " extra stuff");
I see in this video its quite easy to add a textbox and have it drive the filtering of a datagridView. The issue is in this video it seems you have to specific which column to filter based on.
RowFilter = "FirstName like "%' + searchText.Text + '%"
but what if I want it to check all of the fields and show the row if any column has my search string in it
You would want to loop through each column in your row and append an OR comparison
This is really stupid code, but hopefully gives you the gist of it. Something like:
StringBuilder filter = new StringBuilder();
foreach(var column in dataGridView.Columns)
{
if(filter.ToString() == "")
{
filter.Append(column.Name + " like '" + searchText.Text + "'");
}
else
{
filter.Append(" OR ");
filter.Append(column.Name + " like '" + searchText.Text + "'");
}
}
RowFilter = filter.ToString();
You can iterate all reasonable columns and get "like" filter like this:
var search = "search request";
var columnsList = dataGridView.Columns.Cast<DataGridViewColumn>()
.Where(x => x.Visible && x.ValueType == typeof(string))
.Select(x => x.DataPropertyName);
var filter = string.Join(" OR ", columnsList.Select(x => $"{x} like '%{search}%'"));
In my application I am using a dataview for having the filters to be applied where the filter options are passed dynamically.if there are 2 filter parameters then the dataview should be filtered for parameter1 and then by parameter two. I am using a method which is called in a for loop where I am setting the count to the total no.of parameters selected using a listbox but the filtering is done only for the last parameter.
Here is my code:
string str = "";
for (int i = 0; i < listbox.Items.Count; i++)
{
if (listbox.Items[i].Selected)
{
if (str != string.Empty)
{
str = str + "," + listbox.Items[i].Text;
}
else
{
str = str + listbox.Items[i].Text;
}
}
}
string[] items = str.Split(',');
for (int i = 0; i < items.Length; i++)
{
ApplyFilter(items[i],dv);
}
private DataView ApplyFilter(string str,DataView newdv)
{
newdv.RowFilter = "[" + str + "]=" + ddl.SelectedItem.ToString();
return newdv;
}
Please provide a suitable solution .
Thanks in advance...
You should apply your filter altogether, not one by one :
newdv.RowFilter = "Column1 = " + value1 + " AND Column2 = " + value2;
So you can change your code as :
string[] items = str.Split(',');
string filter = string.Empty;
for (int i = 0; i < items.Length; i++)
{
filter += items[i] + " = " + dropdown.SelectedValue;
if (i != items.Length - 1)
{
filter += " AND ";
}
}
newdv.RowFilter = filter;
I think you should build a complete filter string and then set this filter to your DataView.
For example:
StringBuilder sb = new StringBuilder()
for (int i = 0; i < listbox.Items.Count; i++) {
if (!listbox.Items[i].Selected) {
continue;
}
if (sb.Length > 0) {
sb.Append(" and ");
}
sb.AppendFormat("[{0}] = {1}", listbox.Items[i].Text, ddl.SelectedItem);
}
dv.RowFilter = sb.ToString();
DataView dv = new DataView(dt);
string filterText = "some search criteria";
dv.RowFilter = "Column1 + Column2 + Column3 Like '%" + filterText + "%'";
I had a similar problem - but i think solution will be the same for both of them. I have a datatable that needs to be filtered by 5 controls and if they aren't filled - it shouldn't be filtered.
List<string> allParams = new List<string>();
//here add fields you want to filter and their impact on rowview in string form
if (tsPrzelewyTxtOpis.Text != ""){ allParams.Add("Opis like '%" + tsPrzelewyTxtOpis.Text + "%'"); }
if(tsPrzelewyTxtPlatnik.Text != ""){ allParams.Add("Płacący like '%" + tsPrzelewyTxtPlatnik.Text + "%'"); }
if(tsPrzelewyDropDownKonto.Text != "") { allParams.Add("Konto = '" + tsPrzelewyDropDownKonto.Text + "'"); }
if (tsPrzelewyDropDownWaluta.Text != "") { allParams.Add("Waluta = '" + tsPrzelewyDropDownWaluta.Text + "'"); }
if (tsPrzelewyDropDownStatus.Text != "") { allParams.Add("Status = '" + tsPrzelewyDropDownStatus.Text + "'"); }
string finalFilter = string.Join(" and ", allParams);
if (finalFilter != "")
{ (dgvPrzelewy.DataSource as DataTable).DefaultView.RowFilter = "(" + finalFilter + ")"; }
else
{ (dgvPrzelewy.DataSource as DataTable).DefaultView.RowFilter = ""; }