?
Solved

dynamic LINQ string... c#

Posted on 2014-11-16
16
Medium Priority
?
296 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 34

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 28

Assisted Solution

by:Ark
Ark earned 600 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
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
LVL 34

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 28

Expert Comment

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

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 28

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 34

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 34

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 34

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 1400 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 34

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 34

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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

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