Click here to Skip to main content
15,893,588 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to perform multiple where statements in a single linq statement. The following works, but in 3 separate steps. Can it be done in one?

C#
var test = (from prop in typeof(Invoice).GetProperties()
            where prop.PropertyType == typeof (ItemInfo)
               from z in (from item in typeof (ItemInfo).GetProperties()
                          select new Prop{ Name = prop.Name + item.Name, 
                                           PropType = item.PropertyType})
               select z).ToList();
test.AddRange((from prop in typeof(Invoice).GetProperties()
               where prop.PropertyType == typeof(AmountInfo)
                  from z in (from amm in typeof(AmountInfo).GetProperties()
                             select new Prop{ Name = prop.Name + amm.Name, 
                                              PropType = amm.PropertyType })
                  select z).ToList());
test.AddRange((from prop in typeof(Invoice).GetProperties()
               where (prop.PropertyType != typeof(ItemInfo) && 
                      prop.PropertyType != typeof(AmountInfo))
               select new Prop { Name = prop.Name, 
                                 PropType = prop.PropertyType }));
Posted
Updated 24-Oct-11 23:16pm
v2

Since 2/3 of the queries varies (the where and select clauses), I think three queries is probably the right answer, unless you want to put a generic method that can be called to do the select part in any case. But since you're using PropertyInfo that isn't really possible. So the only thing I'd change is to not call GetProperties each time:

var props = typeof(Invoice).GetProperties();

var test = (from props
            where prop.PropertyType == typeof (ItemInfo)
               from z in (from item in typeof (ItemInfo).GetProperties()
                          select new Prop{ Name = prop.Name + item.Name, 
                                           PropType = item.PropertyType})
               select z).ToList();
test.AddRange((from props
               where prop.PropertyType == typeof(AmountInfo)
                  from z in (from amm in typeof(AmountInfo).GetProperties()
                             select new Prop{ Name = prop.Name + amm.Name, 
                                              PropType = amm.PropertyType })
                  select z).ToList());
test.AddRange((from props
               where (prop.PropertyType != typeof(ItemInfo) && 
                      prop.PropertyType != typeof(AmountInfo))
               select new Prop { Name = prop.Name, 
                                 PropType = prop.PropertyType }));


Actually, I probably wouldn't use LINQ here at all.

List<Prop> test = new List<Prop>();
var props = typeof(Invoice).GetProperties();
foreach(PropertyInfo prop in props){
 if(prop.PropertyType == typeof(ItemInfo) || prop.PropertyType == typeof(AmountInfo))
  test.AddRange(typeof(prop.PropertyType).Properties.ForEach(p => new Prop { Name = prop.Name + p.Name, PropType = p.PropertyType});
 else
  test.Add(new Prop { Name = prop.Name, PropType = prop.PropertyType });
}


The standard extension ForEach isn't defined on arrays, I think you can do it like
public static IEnumerable<U> ForEach<T, U>(this T[] values, Func<T,U> action){
 foreach(T t in values) yield return action(t);
}
 
Share this answer
 
Comments
madtag76 25-Oct-11 7:17am    
I had something similar but was asked to do it in linq!
Why not:

C#
var test = (from prop in typeof(Invoice).GetProperties()
            where 
(prop.PropertyType == typeof (ItemInfo)) ||
(prop.PropertyType == typeof(AmountInfo)) || 
((prop.PropertyType != typeof(ItemInfo) &&
                      prop.PropertyType != typeof(AmountInfo)))
               from z in (from item in typeof (ItemInfo).GetProperties()
                          select new Prop{ Name = prop.Name + item.Name,
                                           PropType = item.PropertyType})
 
Share this answer
 
Comments
BobJanova 25-Oct-11 5:57am    
Read the queries more closely, the 'from z' part is different in each one.
madtag76 25-Oct-11 6:11am    
That's exactly my problem.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900