Solved

dynamic LINQ string... c#

Posted on 2014-11-16
16
253 Views
Last Modified: 2016-02-15
At line 1 below, lb.ID may contain lslCity or lstState. Variable filedName at the same line, therefore, could contain "City" or "State" (field names).

Question: How can I insert filedName to replace City at lines 3 and 5 with filedName ?

I see that  filedName is string not a field type. I do not know how to cast and convert to filed name,

This way, I will be able to use one LINQ string for two controls.
          string filedName = lb.ID.Substring(3);
           ListItem[] outputs = (from output in wscgsContext.Searches
                                 orderby output.City
                                 group output by output.City into theGroup
                                 select new ListItem(theGroup.FirstOrDefault().City)).ToArray();

           lb.Items.AddRange(outputs);

Open in new window

0
Comment
Question by:Mike Eghtebas
  • 8
  • 5
  • 3
16 Comments
 
LVL 11

Expert Comment

by:louisfr
ID: 40446483
You can get a property value by name using reflection.
from output in wscgsContext.Searches
orderby (string)output.GetType().GetProperty(filedName).GetValue(output)
group output by output.City into theGroup
select new ListItem(theGroup.FirstOrDefault().City)

Open in new window


You can also create dynamic expressions with the methods found in the Expression class. With T being the type of items in wscgsContext.Searches
ParameterExpression o = Expression.Parameter(typeof(T));
Func<T, string> orderByExpression = Expression.Lambda<Func<T, string>>(Expression.Property(o, filedName), o);

Open in new window

You can then pass the expression to the OrderBy method:
from output in wscgsContext.Searches.OrderBy(orderByExpression)
group output by output.City into theGroup
select new ListItem(theGroup.FirstOrDefault().City)

Open in new window

0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40446497
Hi louisfr,

Thank you for the education. I really appreciate it. I see that City exists in the 1st and 3rd code piece. I was expecting to have fieldName somehow utilized instead.

Sorry for my typo in fieldName, I had filedName instead.

Question: How can I change section 1 and 3 to make them independent of field name City?

Mike

I am try now this:
ListItem[] outputs=from output in wscgsContext.Searches
orderby (string)output.GetType().GetProperty(filedName).GetValue(output)
group output by output.GetProperty(filedName) into theGroup
select new ListItem(theGroup.FirstOrDefault().GetProperty(filedName));

Open in new window


Line 3 has the following error at GetProperty:
'Search' does not contain a definition for 'GetProperty' and no extension method 'GetProperty' accepting a first argument of type 'Search' could be found (are you missing a using directive or an assembly reference?)

I also tried to use ParameterExpression o to plug in place of the field, the following image shows where I am getting errors:errors
Here is another image attempting to utilize section 2 with section 3:error2
0
 
LVL 27

Assisted Solution

by:Ark
Ark earned 150 total points
ID: 40446584
private static object GetPropertyValue(object obj, string property)
{
    System.Reflection.PropertyInfo propertyInfo=obj.GetType().GetProperty(property);
    return propertyInfo.GetValue(obj, null);
}
string filedName = lb.ID.Substring(3);
ListItem[] outputs = (from output in wscgsContext.Searches
        orderby  GetPropertyValue(output, fieldName)
        group output by GetPropertyValue(output, fieldName) into theGroup
        select new ListItem(GetPropertyValue(theGroup.FirstOrDefault(), fieldName))).ToArray();
lb.Items.AddRange(outputs);

Open in new window

0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40446649
Hi Ark,

There is and error in line 9 (or line 12 below) at : The name 'fieldName' does not exist in the current context.
   private static object GetPropertyValue(object obj, string property)
    {
        System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(property);
        return propertyInfo.GetValue(obj, null);
    }
    private void LoadListBoxes(ListBox lb)
    {
           lb.Items.Clear();
           string filedName = lb.ID.Substring(3);
           ListItem[] outputs = (from output in wscgsContext.Searches
                                 orderby GetPropertyValue(output, filedName)
                                 group output by GetPropertyValue(output, fieldName) into theGroup
                                 select new ListItem(GetPropertyValue(theGroup.FirstOrDefault(), fieldName))).ToArray();
           lb.Items.AddRange(outputs);

Open in new window

0
 
LVL 27

Expert Comment

by:Ark
ID: 40446650
oops, sorry
string filedName = lb.ID.Substring(3);
should be
string fieldName = lb.ID.Substring(3);
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40446658
Now I have two errors:
private static object GetPropertyValue(object obj, string property)
    {
        System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(property);
        return propertyInfo.GetValue(obj, null);
    }
    private void LoadListBoxes(ListBox lb)
    {
           lb.Items.Clear();
           string fieldName = lb.ID.Substring(3);
           ListItem[] outputs = (from output in wscgsContext.Searches
                                 orderby GetPropertyValue(output, fieldName)
                                 group output by GetPropertyValue(output, fieldName) into theGroup
                                 select new ListItem(GetPropertyValue(theGroup.FirstOrDefault(), fieldName))).ToArray();
           lb.Items.AddRange(outputs);

Open in new window


Both at line 13:
select new ListItem(GetPropertyValue(t
Argument 1: cannot convert from 'object' to 'string'

select new ListItem(GetPropertyValue(t
The best overloaded method match for 'System.Web.UI.WebControls.ListItem.ListItem(string)' has some invalid arguments
0
 
LVL 27

Expert Comment

by:Ark
ID: 40446664
Either convert GetPropertyValue return value ( return propertyInfo.GetValue(obj, null).ToString()
or
GetPropertyValue(theGroup.FirstOrDefault(), fieldName).ToString()
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40446675
With: return propertyInfo.GetValue(obj, null).ToString()
no change, the same old errors:error4
With: GetPropertyValue(theGroup.FirstOrDefault(), fieldName).ToString();
Cannot order by type 'System.Object'.
0
 
LVL 11

Expert Comment

by:louisfr
ID: 40446693
I hadn't paid attention to that second use of City.
Ark has shown you how to use GetProperty.

To use the expression, you need to put the right type where I used T. I just used T as a placeholder because I didn't know what is the type of wscgsContext.Searches. While reflection can work on unknown types and check the existence of a property at access time, expressions check it when the expression is created and need to know on which type they're working.
The type of orderByExpression was wrong. I could have called Compile to create a delegate and use it as a method to get a cleaner code. Here is new code. Replace T with the right type.
ParameterExpression o = Expression.Parameter(typeof(T));
Func<T, string> getField = Expression.Lambda<Func<T, string>>(Expression.Property(o, fieldName), o);

ListItem[] outputs = (from output in wscgsContext.Searches
                      orderby getField(output)
                      group output by getField(output) into theGroup
                      select new ListItem(getField(theGroup.FirstOrDefault())).ToArray();

Open in new window

0
 
LVL 11

Expert Comment

by:louisfr
ID: 40446697
Either the GetPropertyValue method must be changed to return string
private static string GetPropertyValue(object obj, string property)

Open in new window

or you have to cast its result to string when you call it
(string)GetPropertyValue( ..... )

Open in new window

0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40446710
re:> Replace T with the right type.

After Add New Item, Linq to SQL classes, I dropped table Search to .dbml file in order to use the following code. The database in use is a SQL Server database. I do not know how one determines the type to replace with T as you are mentioning. I have lot to learn and happy to learn all.

 WSCGSoftwareDataContext wscgsContext = new WSCGSoftwareDataContext(cnn);
0
 
LVL 11

Expert Comment

by:louisfr
ID: 40446736
Move your mouse over the Searches property in your LINQ query. Its type should appear.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40447444
re:> Move your mouse over the Searches property in your LINQ query. Its type should appear.

I did this; it read: WSCGSoftwareDataContext.Searches , I dropped Searches and replaced the Ts with only WSCGSoftwareDataContext. I got the following 3 errors:

error5
FYI: With  WSCGSoftwareDataContext.Searches replacing the Ts I got more errors.
0
 
LVL 11

Accepted Solution

by:
louisfr earned 350 total points
ID: 40447473
It should read "xxxxx WSCGSoftwareDataContext.Searches" or something like that. The type is the xxxxx which precedes the name of the property.
You can also click on the "Searches" word and press F12 to go the definition of the property.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40447520
I have:

Table <Search> WSCGSoftwareDataContext.Searches

Shall I replace Ts with:
Table
<Search>
Search
Table <Search>

I tired all, after a response from you, I will report the result.

Thanks,

Mike

I tried Table <Search>, I got the following errors:

1      'System.Func<System.Data.Linq.Table<Search>,string>' is a 'type' but is used like a 'variable'
3.      Argument 1: cannot convert from 'Search' to 'System.Data.Linq.Table<Search>'      
2.      Delegate 'System.Func<System.Data.Linq.Table<Search>,string>' has some invalid arguments

Using F12 on Searches takes me to:
public System.Data.Linq.Table<Search> Searches
0
 
LVL 33

Author Comment

by:Mike Eghtebas
ID: 40447639
I will close this question. We have made good progress. It is continued at:
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_28563821.html
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Jquery/JSON passing value from one function to another 12 37
Printing 1 51
Write to a printer using vb.net 9 26
Obtain cell value using column ID in DataGrid using VB.NET 2 17
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question