i started with this! and i would like to avoid this
private IQueryable<Customer> FilterResult(string search, List<Customer> dtResult, List<string> columnFilters)
{
IQueryable<Customer> results = dtResult.AsQueryable();
results = results.Where(p => (search == null || (p.Name != null && p.Name.ToLower().Contains(search.ToLower()) || p.City != null && p.City.ToLower().Contains(search.ToLower())
&& (columnFilters[0] == null || (p.Name != null && p.Name.ToLower().Contains(columnFilters[0].ToLower())))
&& (columnFilters[1] == null || (p.City != null && p.City.ToLower().Contains(columnFilters[1].ToLower())))
);
return results;
}
by using reflection maybe.... because imagine i have 100 properties it would be easy to mess up ...so i tried this way i would like to use reflection to loop on all properties instead of making references to each of them(properties)
public IQueryable<Aangifte> FilterColumn<T>()
{
try
{
List<Aangifte> v = AangifteGetData.GetData(StartDate, EndDate);
List<Aangifte> v2 = new List<Aangifte>();
Aangifte Foo = new Aangifte();
List<string> propertEntity = new List<string>();
var search = Request.Form.GetValues("search[value]").FirstOrDefault();
int count = -1;
var results = v.AsQueryable();
List<string> columnName = new List<string>();
foreach (var prop in Foo.GetType().GetProperties())
{
var t = "";
if (!prop.Name.Contains("FORMAT"))
{
TVALUE = prop.GetValue(Foo, null);
t= prop.Name;
propertEntity.Add(t);
count++;
}
if (count < propertEntity.Count())
{
var newt = t;
var Z = Request.Form.GetValues("columns[" + count + "][search][value]").FirstOrDefault();
results = results.Where
(
p => (search == null || (t != null && t.ToLower().Contains(search.ToLower())))
&& (Request.Form.GetValues("columns[" + count + "][search][value]").FirstOrDefault() == null || (t != null && t.ToLower().Contains(Request.Form.GetValues("columns[" + count + "][search][value]").FirstOrDefault().ToLower())))
);
}
}
return results;
}
catch (Exception EX)
{
throw EX;
}
}
Related
I have C# code; when run to a line, it throws a System.NullReferenceException.
Here is the line of the code that cause the exception
if (expDic != null && expression != null)
{
expDic.Add(i, expression.ToString())
}
Here is the stack trace in the code
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Sustainability.BusinessObject.CalculationManager.<>c__DisplayClass18_0.<HandleFormulaInner>b__0(Object args) in D:\HK\Desktop\VSTS_2\Sustainability.BusinessObject\Classes\CalculationManager.cs:line 1410
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
I found that both expDic and expression are not null, however it throws a null reference exception.
Here is my code:
int count = table.Rows.Count;
Dictionary<int, string> expDic = new Dictionary<int, string>();
List<Task> taskList = new List<Task>();
for (int f = 0; f < count; f++)
{
DataRow tempformula = table.Rows[f];
string formulaSymbol = Convert.ToString(tempformula[Common.Systems.Sustainability.Constants.IndicatorFormula.Symbol]);
var t = Task.Factory.StartNew(new Action<object>((args) => {
int i = (int)args;
_sem.Wait();
StringBuilder expression = new StringBuilder(1024);
using (DataTable dt = new DataTable())
{
// symbol in the last line of formula
if (exp.EndsWith("+")
|| exp.EndsWith("-")
|| exp.EndsWith("*")
|| exp.EndsWith("/"))
{
exp = exp.Substring(0, exp.Length - 1);
}
object result = dt.Compute(exp, "");
expression.Append(result);
}
}
{
if (!string.IsNullOrWhiteSpace(symbol)
&& expression.Length > 0)
{
if (i + 1 >= count && symbol != ")")
{
}
else if (expression.ToString() != symbol)
{
expression.Append(symbol);
}
}
else if (expression.Length == 0 && symbol == "(")
{
expression.Append(symbol);
}
if (symbol == "days")
{
// calculating average values by days.
if (fromDate != null && toDate != null)
{
int days = toDate.Value.Subtract(fromDate.Value).Days + 1;
expression.Append(days);
}
else
{
expression.Append(1);
}
}
}
//Here is the code will have problem
if (expDic != null && expression != null)
{
expDic.Add(i, expression.ToString());
}
_sem.Release();
}), f);
taskList.Add(t);
}
I am doubting it is caused by the StartNew multithreading pattern,
so what is wrong in my code and how can I fix it?
I'm swapping my values in List Object on some conditions and update List Object value.
Currently, what I'm doing is
- Looping on each object through List
- Check If condition is net
- Swap values
public static void SwapMinMaxIfNull<T>(this IEnumerable<T> rows, string reportfor)
{
if (reportfor.Equals("Comparison"))
{
var row = rows as IEnumerable<RiskBoardDataToExport>;
try
{
if (rows.Any())
{
var Tests = row.Where(min => min.MinGaitSpeed == null && min.MaxGaitSpeed != null).ToList();
if (Tests != null)
{
foreach (RiskBoardDataToExport test in Tests)
{
test.MinGaitSpeed = test.MaxGaitSpeed;
test.MaxGaitSpeed = null;
}
}
// again check for next object
Tests = row.Where(min => min.MinTUGTime == null && min.MaxTUGTime != null).ToList();
if (Tests != null)
{
foreach (RiskBoardDataToExport test in Tests)
{
test.MinTUGTime = test.MaxTUGTime;
test.MaxTUGTime = null;
}
}
// again check for next object
Tests = row.Where(min => min.MinBergScoreSpeed == null && min.MaxBergScoreSpeed != null).ToList();
if (Tests != null)
{
foreach (RiskBoardDataToExport test in Tests)
{
test.MinBergScoreSpeed = test.MaxBergScoreSpeed;
test.MaxBergScoreSpeed = null;
}
}
//.. for brevity
}
}
}
Can I do it in better way? I know about PropertyInfo i.e. Can check property name and get value etc, but, not having any hint to get this done.
Thanks
It's not exactly what you're asking for, but you can combine the clauses in your Where statements and then have a few if statements in the body:
public static void SwapMinMaxIfNull(this IEnumerable<RiskBoardDataToExport> rows,
string reportfor)
{
if (rows = null) return;
if (reportfor.Equals("Comparison", StringComparison.OrdinalIgnoreCase))
{
foreach (var row in rows.Where(r =>
(r.MinGaitSpeed == null && r.MaxGaitSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null)))
{
if (row.MinGaitSpeed == null)
{
row.MinGaitSpeed = row.MaxGaitSpeed;
row.MaxGaitSpeed = null;
}
if (row.MinTUGTime == null)
{
row.MinTUGTime = row.MaxTUGTime;
row.MaxTUGTime = null;
}
if (row.MinBergScoreSpeed == null)
{
row.MinBergScoreSpeed = row.MaxBergScoreSpeed;
row.MaxBergScoreSpeed = null;
}
}
}
}
As this is an operation where order of the items in the list does not matter, you can easily speed this up by parallelization (you can read up on that here).
So, what you should do, is handle this foreach loop in a parallel way and combine it with Rufus L's optimized code for the fastest result.
var rows = rows.Where(r =>
(r.MinGaitSpeed == null && r.MaxGaitSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null) ||
(r.MinBergScoreSpeed == null && r.MaxBergScoreSpeed != null))
Parallel.ForEach(rows, (row) => {
{
if (row.MinGaitSpeed == null)
{
row.MinGaitSpeed = row.MaxGaitSpeed;
row.MaxGaitSpeed = null;
}
if (row.MinTUGTime == null)
{
row.MinTUGTime = row.MaxTUGTime;
row.MaxTUGTime = null;
}
if (row.MinBergScoreSpeed == null)
{
row.MinBergScoreSpeed = row.MaxBergScoreSpeed;
row.MaxBergScoreSpeed = null;
}
}
Note that this requires the System.Threading.Tasks namespace, that's where the Parallel class is.
I am putting together simple generic comparer for unit testing.
I don't want to use IComparable interface because there is just too much classes that would need to implement it, and it will be only used in Unit tests so performance of reflection is not an issue.
So far I have this:
public IEnumerable<NonEqualProperty> Compare<T>(T first, T second) where T : class
{
var list = new List<NonEqualProperty>();
var type = first.GetType();
var properties = type.GetProperties();
var basicTypes = properties.Where(p => !p.PropertyType.IsClass && !p.PropertyType.IsInterface
|| p.PropertyType == typeof(string));
foreach (var prop in basicTypes)
{
var value1 = prop.GetValue(first, null);
var value2 = prop.GetValue(second, null);
if (value1 != null && value2 != null && value1.Equals(value2) || value1 == null && value2 == null )
continue;
list.Add(new NonEqualProperty(prop.Name, value1, value2));
}
var enumerableTypes =
from prop in properties
from interfaceType in prop.PropertyType.GetInterfaces()
where interfaceType.IsGenericType
let baseInterface = interfaceType.GetGenericTypeDefinition()
where prop.PropertyType != typeof(string) && baseInterface == typeof(IEnumerable<>) || baseInterface == typeof(IEnumerable)
select prop;
foreach (var prop in enumerableTypes)
{
var collection = prop.GetValue(first, null);
}
return list;
}
So comparison of all simple types + string works.
Now I would like to iterate through IEnumerable (it's always enumerable of a class, though it would be great to take care of the case when it's not) on both sides and compare values using recursion. Something like this:
foreach (var prop in enumerableTypes)
{
var typeOfItemsInList= ...;
var collection1 = (IEnumerable<typeOfItemsInList>) prop.GetValue(first, null);
var collection2 = (IEnumerable<typeOfItemsInList>) prop.GetValue(second, null);
for (int i = 0; i < collection1.Count; i++)
{
var item1 = collection1[i];
var item2 = collection2[i];
Compare<typeOfItemsInList>(item1, item2, list);
}
}
How would I achieve that?
Unequal count, or order of items in lists are not taken into account here - I would fix it later.
Something similar to this:
public static IEnumerable<NonEqualProperty> Compare<T>(T first, T second) where T : class {
var list = new List<NonEqualProperty>();
var type = first.GetType();
var properties = type.GetProperties();
var basicTypes = properties.Where(p => !p.PropertyType.IsClass && !p.PropertyType.IsInterface
|| p.PropertyType == typeof(string));
foreach (var prop in basicTypes) {
var value1 = prop.GetValue(first, null);
var value2 = prop.GetValue(second, null);
if (object.Equals(value1, value2))
continue;
list.Add(new NonEqualProperty(prop.Name, value1, value2));
}
var enumerableTypes =
from prop in properties
where prop.PropertyType == typeof(IEnumerable) ||
prop.PropertyType.GetInterfaces().Any(x => x == typeof(IEnumerable))
select prop;
foreach (var prop in enumerableTypes) {
var value1 = (IEnumerable)prop.GetValue(first, null);
var value2 = (IEnumerable)prop.GetValue(second, null);
if (object.Equals(value1, value2))
continue;
if (value1 == null || value2 == null) {
list.Add(new NonEqualProperty(prop.Name, value1, value2));
continue;
}
IEnumerator enu1 = null, enu2 = null;
try {
try {
enu1 = value1.GetEnumerator();
enu2 = value2.GetEnumerator();
int ix = -1;
while (true) {
bool next1 = enu1.MoveNext();
bool next2 = enu2.MoveNext();
ix++;
if (!next1) {
while (next2) {
list.Add(new NonEqualProperty(prop.Name + "_" + ix, "MISSING", enu2.Current));
ix++;
next2 = enu2.MoveNext();
}
break;
}
if (!next2) {
while (next1) {
list.Add(new NonEqualProperty(prop.Name + "_" + ix, enu1.Current, "MISSING"));
ix++;
next1 = enu1.MoveNext();
}
break;
}
if (enu1.Current != null) {
var type1 = enu1.Current.GetType();
if ((type1.IsClass || type1.IsInterface) && type1 != typeof(string)) {
continue;
}
}
if (enu2.Current != null) {
var type2 = enu2.Current.GetType();
if ((type2.IsClass || type2.IsInterface) && type2 != typeof(string)) {
continue;
}
}
if (!object.Equals(enu1.Current, enu2.Current)) {
list.Add(new NonEqualProperty(prop.Name + "_" + ix, enu1.Current, enu2.Current));
}
}
} finally {
var disp2 = enu2 as IDisposable;
if (disp2 != null) {
disp2.Dispose();
}
}
} finally {
var disp1 = enu1 as IDisposable;
if (disp1 != null) {
disp1.Dispose();
}
}
}
return list;
}
I'm using the IEnumerable non-generic interface. Note that I'm doing the type-test on each element.
To not change the NonEqualProperty class I'm saving the ix of the difference directly in the prop.Name (so like SomeCollection_0, SomeCollection_1 if the different elements are 0 and 1). Normally I would add an Index property to NonEqualProperty For the "missing" elements I'm using a "MISSING" string, that is ok if you want to take a look at it with the debugger, but there are better ways to do it (add another property "Missing" to NonEqualProperty for example, or do a
public static readonly object Missing = new object();
and use it for missing values.
There are other ways without using the IEnumerable interface, like a:
private static IEnumerable<NonEqualProperty> CompareCollection<T>(IEnumerable<T> firstColl, IEnumerable<T> secondColl) {
var list = new List<NonEqualProperty>();
// Do the comparison
return list;
}
private static MethodInfo CompareCollectionMethod = typeof(Program).GetMethod("CompareCollection", BindingFlags.Static | BindingFlags.NonPublic);
and then
var value1 = (IEnumerable)prop.GetValue(first, null);
var value2 = (IEnumerable)prop.GetValue(second, null);
if (object.Equals(value1, value2))
continue;
if (prop.PropertyType != typeof(IEnumerable)) {
var ienumt = prop.PropertyType.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>)).FirstOrDefault();
if (ienumt != null) {
var t = ienumt.GetGenericArguments(); // T of IEnumerable<T>
if ((t[0].IsClass || t[0].IsInterface) && t[0] != typeof(string)) {
continue;
}
var method = CompareCollectionMethod.MakeGenericMethod(t);
var result = (IEnumerable<NonEqualProperty>)method.Invoke(null, new[] { value1, value2 });
list.AddRange(result);
continue;
}
}
if (value1 == null || value2 == null) {
list.Add(new NonEqualProperty(prop.Name, value1, value2));
continue;
}
// continue with the code for non-generic IEnumerable
IEnumerator enu1 = null, enu2 = null;
I will explain my Problem
so Firstly, I use Predicates Linq for Build Where clause dynamically.
I have to build dynamically because I don't know how many parameters will come. Let me give an example. For the A column can be one parameters however, for the B column can be 2 parameters like either value 'Gas' or 'Oil' which select but that's big problem I can not combine for these 2 column correctly.
So as a result, this code work but It return 0 Items. But there are I know.
public List<CarEntity> GetSearchByKCriteria(int cityId, List<string> fuelType, List<string> gearType, List<string> budget,
List<string> caroser, List<string> enginePower)
{
Expression<Func<Car, bool>> query = null;
Expression<Func<Car, bool>> combine = null;
foreach (var bud in budget)
{
if (budget.Count >= 1)
{
if (bud == "1")
{
if (budget.Count > 1)
{
query = car => car.Budget >= 20000 && car.Budget <= 34999;
}
else
{
query = car => car.Budget >= 20000 && car.Budget <= 34999;
}
}
else if (bud == "2")
{
if (query != null)
{
combine = car => (car.Budget >= 35000 && car.Budget <= 49999);
query = query.Or(combine);
}
else
{
query = car => car.Budget >= 35000 && car.Budget <= 49999;
}
}
}
}
foreach (var caros in caroser)
{
if (caros != "-1" && !string.IsNullOrEmpty(caros))
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("karoser"))
{
combine = car => (car.Karoser == caros);
query = query.And(combine);
}
else
{
combine = car => car.Karoser == caros;
query = query.And(combine);
}
}
else
{
query = car => car.Karoser == caros;
}
}
}
foreach (var fuel in fuelType)
{
if (fuel != "-1" && !string.IsNullOrEmpty(fuel))
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("yakituru"))
{
combine = car => (car.YakitTuru==fuel);
query = query.Or(combine);
}
else
{
combine = car => car.YakitTuru == fuel;
query = query.And(combine);
}
}
else
{
query = car => car.YakitTuru == fuel;
}
}
}
foreach (var gear in gearType)
{
if (gear!="-1"&& !string.IsNullOrEmpty(gear))
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("sanzimantipi"))
{
combine = car => (car.SanzimanTipi == gear);
query = query.Or(combine);
}
else
{
combine = car => car.SanzimanTipi == gear;
query = query.And(combine);
}
}
else
{
query = car => car.SanzimanTipi == gear;
}
}
}
foreach (var engine in enginePower)
{
if (enginePower.Count >= 1)
{
if (engine == "1")
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("silindirhacmi"))
{
combine = car => (car.SilindirHacmi >= 0 && car.SilindirHacmi <= 1600);
query = query.Or(combine);
}
else
{
combine = car => (car.SilindirHacmi >= 0 && car.SilindirHacmi <= 1600);
query = query.And(combine);
}
}
else
{
query = car => car.SilindirHacmi >= 0 && car.SilindirHacmi <= 1600;
}
}
if (engine == "3")
{
if (query != null)
{
if (query.Expand().ToString().ToLower().Contains("silindirhacmi"))
{
combine = car => (car.SilindirHacmi >= 1601 && car.SilindirHacmi <= 1800);
query = query.Or(combine);
}
else
{
combine = car => (car.SilindirHacmi >= 1601 && car.SilindirHacmi <= 1800);
query = query.And(combine);
}
}
else
{
query = car => car.SilindirHacmi >= 1601 && car.SilindirHacmi <= 1800;
}
}
}
using (var context = DataContextFactory.CreateContext())
{
var result = (from fkCar in context.Car.Where(query)
join pkCarBrand in context.CarBrand on fkCar.Marka equals pkCarBrand.ID
where fkCar.IsActive == true
select new
{
entity = fkCar,
joinEntity = pkCarBrand
});
List<CarEntity> theCarList = new List<CarEntity>();
foreach (var item in result)
{
CarEntity theEntity = Mapper.Map(item.entity);
theEntity.CarBrand = Mapper.Map(item.joinEntity);
theCarList.Add(theEntity);
}
return theCarList;
}
}
So thanks for reply,
I faced a similar challenge a while back, where I wanted to have a list of allowed values for an attribute where, if matched, the associated instance would pass the filter. I came up with the following extension method:
static public Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
if (null == valueSelector)
{
throw new ArgumentNullException("valueSelector");
}
if (null == values) { throw new ArgumentNullException("values"); }
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
{
return e => false;
}
var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
This is based on the discussion and code posted at http://www.velocityreviews.com/forums/t645784-linq-where-clause.html
the code
Settings setting_ = .... // not null
foreach( var item in ItemsCollection)
{
var tt1 = item.GetTT1();
var tt2 = item.GetTT2();
if( tt2 != null && tt1 != null )
{
if( !string.IsNullOrEmpty( settings_.Name ) )
{
tt2.Rename( tt1, setting_.Name );
}
if( setting_ .Settings != null )
{
tt2.ChangeSettings( tt1, setting_.Settings );
}
if( setting_ .Location != null )
{
tt2.ChangeLocation( tt1, setting_.Location );
}
}
}
Because the setting_ is not change at any iteration of the foreach loop => i need to check only once the 3 if .... ( before get into the foreach loop )
But the tt1 & tt2 are change each foreach iteration ...
How can i write this code better with only one check of the setting_ ?
one possible is this
private void defineAction( TT1 tt1 , TT2 tt2, Setting setting )
{
List<Action> action = new List<Action>();
if( !string.IsNullOrEmpty( settings_.Name ) )
{
action.Add( () => tt2.Rename( tt1, setting_.Name )
}
if( setting_ .Settings != null )
{
action.Add( () => tt2.ChangeSettings( tt1, setting_.Settings );
}
if( setting_ .Settings != null )
{
action.Add( () => tt2.ChangeLocation( tt1, setting_.Location );
}
}
and use the List to make the action ..
but i need to call this method each iteration and i want to make it better
Now that I understand from your previous comments what you're trying to do you can create a collection of actions rather than using simple if statements. If may or may not be better performing, since you'd have the cost of the iterator. If the collection is large, it would probably be useful to check if you're going to do anything before iterating over it.
Settings setting_ = .... // not null
var actions = new List<Action<TT1,TT2>>();
if (!string.IsNullOrEmpty(setting_.Name))
{
actions.Add((t1,t2) => t2.Rename(t1, setting_.Name););
}
if (setting_.Settings != null)
{
actions.Add((t1,t2) => t2.ChangeSettings(t1, settings_.Settings));
}
if (setting_.Location != null)
{
actions.Add((t1,t2) => t2.ChangeLocation(t1, settings_.Location));
}
if (actions.Any())
{
foreach( var item in ItemsCollection)
{
var tt1 = item.GetTT1();
var tt2 = item.GetTT2();
if (tt1 == null || tt2 == null)
{
continue;
}
foreach (var action in actions)
{
action(tt1,tt2);
}
}
}
Though I still think it's easier if you just precompute the conditions - I was confused by setting_.Settings before.
Settings setting_ = .... // not null
var changeName = !string.IsNullOrEmpty(setting_.Name);
var changeSetting = setting_.Settings != null;
var changeLocation = setting_.Location != null;
if (changeName || changeSetting || changeLocation)
{
foreach (var item in ItemCollection)
{
var tt1 = item.getTT1();
var tt2 = item.getTT2();
if (tt1 == null || tt2 == null)
{
continue;
}
if (changeName)
{
tt2.Rename(tt1, setting_.Name);
}
if (changeSetting)
{
tt2.ChangeSettings(tt1, settings_.Settings);
}
if (changeLocation)
{
tt2.ChangeLocation(tt1, settings_.Location);
}
}
}
It took me a while to decipher your question but I think I understand you. Here's what you could do:
var actions = new List<Action<Item, Item>>();
if (!string.IsNullOrEmpty(setting_.Name))
{
actions.Add((tt1, tt2) =>
{
if (tt1 != null && tt2 != null)
tt2.Rename(tt1, setting_.Name);
});
}
if (setting_.Settings != null)
{
actions.Add((tt1, tt2) =>
{
if (tt1 != null && tt2 != null)
tt2.ChangeSettings(tt1, setting_.Settings);
});
}
if (setting_.Settings != null)
{
actions.Add((tt1, tt2) =>
{
if (tt1 != null && tt2 != null)
tt2.ChangeLocation(tt1, setting_.Location);
});
}
foreach (var item in itemCollection)
{
var tt1 = item.GetTT1();
var tt2 = item.GetTT2();
actions.ForEach(a => a(tt1, tt2));
}