LINQ filter Datatable by n Columns
http://stackoverflow.com/questions/10451015/linq-filter-datatable-by-n-columns
Remove the parameters
columnFilter and expression and instead pass your data in a collection of columnsFilter and expression . You can create a custom class or just use a list ofTuple<string,string> like this:
To create the Tuple you are doing something like this:
Then modify the code in your queries to something like this:
Alternatively, you can use
PredicateBuilder :
Since I haven't test this, I wonder if you need to do
dataTableToPage.AsQueryable() instead of AsEnumerable() ? | |||
You shouldn't query your DataTable in a class or method where you want to do pagination. That's breaking the responsibility of the class. You should rather separate those two behavior.
You can do it like that:
Now that code is only caring about paging.
And for the query:
I did them as Extension methods because in this case you are just extending that class behavior and they read nicely.
And you can use the code by doing:
| |||||||||||||
|
0
|
I think you will need some sort of parser/walker to transform your string expressions into linq expressions. Once you have that you 'll be able to apply those filters. You need something like a tiny linq provider. At least that's the only way to come to my mind...
| ||
www.google.com
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
public delegate int Add(int x, int y);
static void Main(string[] args)
{
//Func<double, double> cpointer = r => r * 3.14;
//Console.WriteLine(cpointer(4));
//Console.ReadKey();
//Add objAdd = AddTwoNumbers;
//Add objAdd = (a, b) => a + b;
//Console.WriteLine(objAdd(4,5));
DataTable dt = new DataTable();
dt.Columns.Add("AssetType", typeof(string));
dt.Columns.Add("AssetDescription", typeof(string));
dt.Columns.Add("PublishDate", typeof(DateTime));
dt.Columns.Add("Distribution", typeof(string));
dt.Columns.Add("GoalsBasedSegment", typeof(string));
dt.Rows.Add("Document", "Material Document", "9/23/2014", "Client-Approved#Internal", "Segment5#Segment9");
dt.Rows.Add("Article", "Article Document", "9/27/2014", "Internal#Forms", "Segment12#Segment9");
dt.Rows.Add("Page", "Page Document", "9/29/2014", "Client-Approved#Internal", "Segment5#Segment9");
string SelectonCriteria = "AssetType:Document$#AssetDescription:Matrial Document$#PublishDate:9/23/2014$#Distribution:,Client-Approved#Internal$#GoalsBasedSegment:,Segment5#Segment8";
string[] controlSplit = SelectonCriteria.Split(new string[]{"$#"},StringSplitOptions.None);
var colsExpsTest = new List<Tuple<string, string>>();
foreach (var item in controlSplit)
{
var coloumnSplit=item.Split(':');
colsExpsTest.Add(new Tuple<string, string>(coloumnSplit.ElementAt(0), coloumnSplit.ElementAt(1).TrimStart(',')));
}
DataTable dttest = Page(dt, colsExpsTest);
dttest = dttest.AsEnumerable().Distinct(DataRowComparer.Default).CopyToDataTable();
var test = 1;
}
public static DataTable Page(DataTable dataTableToPage, IList<Tuple<string, string>> columnToExpression)
{
DataTable dt = dataTableToPage.Clone();
IEnumerable<DataRow> productsQuery;
foreach (var pair in columnToExpression)
{
string columnFilter = pair.Item1;
string expression = pair.Item2;
if (columnFilter == "Distribution" || columnFilter == "GoalsBasedSegment")
{
//string[] sTypes = expression.Split(',');
productsQuery = dataTableToPage.AsEnumerable().Where(r => r.Field<string>(columnFilter).Contains(expression));
//productsQuery = dataTableToPage.AsEnumerable().ToList().Where(item => expression.Split(',').Contains(item.Field<string>(columnFilter).ToString()));
}
else
{
productsQuery = dataTableToPage.AsEnumerable().Where(dr => dr[columnFilter].ToString().IndexOf(expression, StringComparison.OrdinalIgnoreCase) >= 0);
}
foreach (var item in productsQuery)
{
dt.ImportRow(item);
}
dt.AcceptChanges();
}
return dt;
}
}
}
//dt.Rows.Add("203456879", "Smith", "12 Main Street, Newyork, NY", 45);
//dt.Rows.Add("203456880", "SAM", "345 Main Ave, Dayton, OH", 55);
//dt.Rows.Add("203456881", "Sue", "32 Cranbrook Rd, Newyork, NY", 65);
//dt.Rows.Add("203456882", "Winston", "1208 Alex St, Newyork, NY", 65);
//dt.Rows.Add("203456883", "Mac", "126 Province Ave, Baltimore, NY", 85);
//dt.Rows.Add("203456884", "SAM", "126 Province Ave, Baltimore, NY", 95);
//var test = 1;
//string sample = ",liger, unicorn, snipe";
//sample = sample.TrimStart(','); // to remove just the first comma
//sample = sample.Trim().TrimStart(',');
//var myProftype = profiles.First(p => p.Id == StUserSet.utoken);
//string sProftype = myProftype.profile_accomtypes;
//string[] sTypes = sProftype.Split(',');
//var myTAccomtypes = propTypes.Where(r => sTypes.Contains(r.Field<int>("Id").ToString()));
//StringBuilder sb = new StringBuilder(0);
//foreach (PropType s in myTAccomtypes)
//{
// sb.Append("<dd>" + s.Description + "</dd>");
//}
//myList = myList.Where(item => indexList.Split(',').Contains(item.IndexID.ToString())).ToList();
//var colsExps = new List<Tuple<string, string>>();
//colsExps.Add(new Tuple<string, string>("Name", "John"));
//colsExps.Add(new Tuple<string, string>("AGE", "95"));
//dataTableToPage = dataTableToPage.AsEnumerable().Where(dr => dr[columnFilter].ToString().IndexOf(expression,
// StringComparison.OrdinalIgnoreCase) >= 0).CopyToDataTable();
//productsQuery = from dr in dataTableToPage.AsEnumerable()
// where dr[columnFilter].ToString().IndexOf(expression, StringComparison.OrdinalIgnoreCase) >= 0
// select dr;
//dataTableToPage = (from dr in dataTableToPage.AsEnumerable()
// where dr[columnFilter].ToString().Contains(expression)
// select dr).CopyToDataTable();
//public static int AddTwoNumbers(int a,int b)
//{
// return a + b;
//}
PredicateBuilder
which should help you do your OR comparisons. – Brad Rem May 4 '12 at 16:26dataTableToPage.AsQueryable()
and I am receiving an error because of it :( – rpmlins May 4 '12 at 18:07query = query.Where(predicate.Compile());
Thank you very much @Brad – rpmlins May 4 '12 at 18