This is a migrated thread and some comments may be shown as answers.

Generic Search in Winform App

1 Answer 45 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Guy
Top achievements
Rank 1
Guy asked on 18 May 2011, 02:56 AM
When the user wants to search, the app is coded to hide buttons and navbars and a blank database record is added to the bindingsource list at the end and the bindingsource is positioned to the end of the list.  Hence, this blank record serves as a buffer to collect values for a search routine using the same UI as data entry.  Inside the search (after the user has clicked to get results) routine, there is code as follows where _s is said record of type Document:

var r = _xdb.Documents;
             
if (!string.IsNullOrEmpty(_s.Comments))            
   r = r.Where(d => d.Comments.Contains(_s.Comments));
 
if (!string.IsNullOrEmpty(_s.Electronic_Document)) 
   r = r.Where(d => d.Electronic_Document.Contains(_s.Electronic_Document));
 
if (!string.IsNullOrEmpty(_s.ManfSupplier))        
   r = r.Where(d => d.ManfSupplier.Contains(_s.ManfSupplier));
 
...

I tried the following code first because I would like to generalize this idea to any record, not just this Document type:

foreach (FieldInfo fi in _s.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
    object v = fi.GetValue(_s);
    if (v == null) continue;
 
    if (fi.FieldType != typeof(int) && fi.FieldType != typeof(string))
        continue;
 
    if (fi.FieldType == typeof(int) && (int)v == 0)
        continue;
                 
    if (fi.FieldType == typeof(string))
    {
        if (string.IsNullOrEmpty(v.ToString()))
            continue;
        results = results.Where(d => fi.GetValue(d).ToString().Contains(v.ToString()));
    }
    else
        results = results.Where(d => fi.GetValue(d) == v);
}

I know this last snippet needs work, as I have dates to handle.  The Where call throws an exception stating that the server does not support "fi.GetValue".  I understand that this may be an issue with the Telerik LINQ compiler which seems to pass stuff onto the server if it doesn't understand it.  I know there are several ways to skin a cat in LINQ.  I would like to skin this cat using Telerik's tools.

Is there a way to do generic search using this Reflection idea?

Regards,
Guy


1 Answer, 1 is accepted

Sort by
0
PetarP
Telerik team
answered on 20 May 2011, 03:58 PM
Hi Guy,

 Unfortunately we cannot pass fi.GetValue(d) to the database server and thus using approach like this is not possible.
What you can do is add an extension method to our persistent type that will return the field value based on a field name given. The method signature should be something like this:

public static T FieldValue<T>(this object persistentInstance, string nameOfPersistentField)
then you can rewrite your linq query like this:
foreach (FieldInfo fi in _s.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
    object v = fi.GetValue(_s);
    if (v == null) continue;
  
    if (fi.FieldType != typeof(int) && fi.FieldType != typeof(string))
        continue;
  
    if (fi.FieldType == typeof(int) && (int)v == 0)
        continue;
                  
    if (fi.FieldType == typeof(string))
    {
        if (string.IsNullOrEmpty(v.ToString()))
            continue;
        results = results.Where(d => d.FieldValue<string>(fi.Name).Contains(v.ToString()));
    }
    else
    {       
        results = results.Where(d => d.FieldValue<YYY>(fi.Name) == v);
    }
}
where YYY is the field type.


All the best,
Petar
the Telerik team
Q1’11 SP1 of Telerik OpenAccess is available for download; also available is the Q2'11 Roadmap for Telerik OpenAccess ORM.
Tags
General Discussions
Asked by
Guy
Top achievements
Rank 1
Answers by
PetarP
Telerik team
Share this question
or