ASP.Net Custom Paging (w/ C#) - c#

Cenario:
I have a GridView bound to a DataSource, every column is sortable.
my main query is something like:
select a, b, c, d, e, f from table order by somedate desc
i added a filter form where i can define values to each one of the fields and get the results of a where form. As a result from this, i had to do a custom sorting so that when i sort by a field, i am sorting the filtered query and not the main one.
Now i have to do custom paging, for the same reason, but i don't understand the philosophy of it: I want to guarantee that i can:
filter the results
sort by a column
when i click on page 2, i get page two of the filtered and sorted results
I don't know what i have to do, so i can bind the GV with this. My sorting Method, that is working just fine looks something like:
string condition = GetConditions(); //gets a string like " where a>1 and b>2" depending on the filter the user defines
string query = "select a, b, c, d, e, f from table ";
string direction = (e.SortDirection == SortDirection.Ascending)? "asc": "desc";
string order = " order by " + e.SortExpression + " " + direction;
UtilizadoresDataSource.SelectCommand = query + condition + order;
i've never done custom paging, i am trying:
GetConditions() //no problem here
How can i find out how the GridView is sorted (by what field and sortingorder)?
thank you very much

You can use ROW_NUMBER to get the number of rows that a query is returning and then filter only those element that will be visible for the given page. For example you should add ROW_NUMBER function in the select clause and add the filtering in the where cause.
string condition = GetConditions(); //gets a string like " where a>1 and b>2" depending on the filter the user defines
string query = "select ROW_NUMBER() OVER(ORDER BY " + order + ") a, b, c, d, e, f from table ";
string direction = (e.SortDirection == SortDirection.Ascending)? "asc": "desc";
string order = " order by " + e.SortExpression + " " + direction;
condition = condition + " RowNo BETWEEN ((#Page - 1) * #PageSize + 1) AND (#Page * #PageSize) "
UtilizadoresDataSource.SelectCommand = query + condition + order;
You can find a more detailed example here.It also contains a sample project with binding a grid.
P.S. I would suggest you to create a stored procedure and pass the parameters from the code behind. This can increase the speed and also it easier to maintain.

Related

Search rows in Datatable with string a fast

I need to select rows from with a string of IDs that are not the PK and int value x,
and datatable.select() takes to much time. Is there faster way to select them.
this is my code:
String a = "Id1, id2, ...";
meldunng.Select("columnname1 = " + 2 " AND columnname2 IN (" + a + ")")
If my question is confusing or I have worded it wrong please tell me.
Thanks in andvance
You could use a HashSet<string> to improve performance and LINQ for the query:
var ids = new HashSet<string>(new[] {"Id1", "id2", "id3"}, StringComparer.OrdinalIgnoreCase); // i guess you want to ignore the case
var matchingRows = meldunng.AsEnumerable()
.Where(row => row.Field<int>("columnname1") == 2 && ids.Contains(row.Field<string>("columnname2")));
Note that this is just the LINQ query and you need to "materialize" it to something, for example a DataRow[]:
DataRow[] resultRows = matchingRows.ToArray();

Add "Contains" filter to existing list of filters in datagridview

I am currently allowing the user to filter through values of a datagridview, by letting them choose the column name, operand, and value.
Column name, operand and value get saved to a ColumnFilter instance. The user is also able to set more than one filters to the grid. My actual filtering works like so:
public void ApplyFilters(List<ColumnFilter> filters)
{
BindingSource bs = (BindingSource)dataGridView1.DataSource;
bs.Filter = string.Join(" AND ", filters.Select(filter=>string.Format("{0} {1} '{2}'", filter.ColumnName, filter.Operand, filter.Value)).ToArray());
dataGridView1.DataSource = bs;
}
This works fine for as many filters as you might want to apply. My current list of available operands is : {=, >, <, >=,<=,<>}. Now however I would like to add one more operand, the Contains. So if someone wants to search through a string column, they can do it through this operand.
One simple way to filter for the Contains is:
var dt = (DataTable)dataGridView1.DataSource;
dt.DefaultView.RowFilter = string.Format("Column like '%{0}%'", txtBoxSearch.Text.Trim().Replace("'", "''"));
dataGridView1.DataSource = dt;
This is just an example. How can I make my ApplyFilters function generic enough to cater for the Contains operand?
Just before setting the binding source filter, set the filter.Value conditionally.
filter.Value = filter.Operand == "like" ? "'%" + filter.Value + "%'" : filter.Value;
However, flexible filtering is still more complicated than this. What if your column is not text data?
Update
Instead of what I said, put that expression inside your Select
bs.Filter = string.Join(" AND ",
filters.Select(filter=>string.Format("{0} {1} '{2}'",
filter.ColumnName, filter.Operand,
filter.Operand == "like" ? "'%" + filter.Value + "%'" : filter.Value)).ToArray());

Linq to SQL JOIN?

I am trying to query names in one table and then use that result to pull the master records into a DataGridView. So what I need to do is get the names from the interest table that are like what is put into text boxes then use those results to pull the data from the CaseSelector table and set the bindingsource filter to those results. Why can't I seem to set results to the caseSelectorBindingSourceFilter
var results = from CaseSelector in db.CaseSelectors
from Interest in db.Interests
where SqlMethods.Like(Interest.First, txtFirst.Text) && SqlMethods.Like(Interest.Last, txtLast.Text)
select CaseSelector;
caseSelectorBindingSource.Filter = ("CaseNumberKey =" + results);
You can find examples for LINQ join queries here:
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
I don't know your DB schema but you're looking for something along the lines of:
from c in db.Cases
join i in db.Interest on i.CaseNumberKey equals c.CaseNumberKey
select c
What you've just retrieved is a SQL Set of the valid caseNumberKeys.
Your casefilter should be something like
caseSelectorBindingSource.Filter = "CaseNumberKey in " + interestsresultsAsSQLSET;
You'll have to iterate over the interestsresults and convert it to the string representation of a SQLSET. If you're feeling lucky, you could just try to .toString() it and see what happens.
string interestsResultsAsSQLSet = "(";
//write most of them
for(int i=0; i<interestsresults.size() - 1; i++) {
interestsResultAsSQLSet.append(interestsresults[i] + ",");
//write the last one, with right paren
interestsresults.append(interestsresults[interestsresults.size() -1] + ")");
I write Java all day, ignore my basic language errors. :P

DatatGrid Itemsource using Linq i cant select any record except first

Hey im currently having problems with WPF Datagrid using linq, currently im displaying a group of records from three tables into a datagrid, this works fine and i retrieve all the relevant information correctly.
However when i load the datagrid and i click on for example the 3rd record it selects the first record and i cant change it. I can use Ctrl + click to deselect the first record.
I dont know why its doing this but ive narrowed it down to my linq query, ive tried to write a more complex linq query using joins etc, it retrieves the same data but i still have this problem :/ any ideas would be good...thank you in advance
apptGrid.ItemsSource = (from o in DbList.OrderedAppointmentList()
from s in DbList.StaffList()
from c in DbList.ClientList()
where o.Appointment_Date == apptDatePicker.SelectedDate.Value
&& o.Staff_Staff_ID == s.Staff_ID && o.Client_Client_ID == c.Client_ID
select new
{
o.Appointment_Date,
o.Appointment_Time,
o.Duration,
StaffName =
((s.Middle_Name_s_ != null) ? s.First_Name + " " + s.Middle_Name_s_ + " " + s.Last_Name : s.First_Name + " " + s.Last_Name),
ClientName =
((c.Middle_Name_s_ != null) ? c.First_Name + " " + c.Middle_Name_s_ + " " + c.Last_Name : c.First_Name + " " + c.Last_Name)
});
Try a ToList() at the end of the query.
I had something similar like you, but to me happen, that when i add rows with the same data information, the selection seems to be crazy. what i did was not give a linq query as a itemsource else put all the information into a List and next pass it to the item source.
"ive tried to write a more complex linq query using joins etc,"
That's never going to help.
Write a program that is human readable (and not just computer readable). And I can bet, you will find the problem and the solution in that iteration.

Select statamen of a Datarow array

I have the following code, first I filter by a foreign key, but then with that result I need to filter more with dates.
But I cant understand the syntax of the select() method of a datarow array given below.
UC021_WizardStepSelectUnitDataSet.WizardStepSelectUnits_UnitsSelectedInOtherAgreementsRow[] datarows =
_uc021_WizardStepSelectUnitDataSet.WizardStepSelectUnits_UnitsSelectedInOtherAgreements.Select(
"UnitId = " + row.UnitID).Cast
<UC021_WizardStepSelectUnitDataSet.WizardStepSelectUnits_UnitsSelectedInOtherAgreementsRow>().ToArray();
DataRow[] dr = _uc021_WizardStepSelectUnitDataSet.
WizardStepSelectUnits_UnitsSelectedInOtherAgreements.Select(
"UnitId = " + row.UnitID);
if (datarows.Length > 0)
{
dr.Select("");
}
The Select on DataTable is similar to a Where clause you add to a query, in this case its filtering the records matching the row.UnitID which is to be found under column UnitId of the DataTable.
You can add multiple conditions by using AND within select like
.Select("UnitId = " + row.UnitID+ " AND IsActive='Y'")

Categories

Resources