Solved

dynamic LINQ string... c#

Posted on 2014-11-16
16
243 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
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
Comment Utility
oops, sorry
string filedName = lb.ID.Substring(3);
should be
string fieldName = lb.ID.Substring(3);
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
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
Comment Utility
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
Comment Utility
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
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 11

Expert Comment

by:louisfr
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Move your mouse over the Searches property in your LINQ query. Its type should appear.
0
 
LVL 33

Author Comment

by:Mike Eghtebas
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

772 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now