Generic Search<T>() method for DataManager?

8 posts, 0 answers
  1. Shane Milton
    Shane Milton avatar
    219 posts
    Member since:
    Dec 2003

    Posted 27 Feb 2010 Link to this post

    (I'm using the DSW for WCF Endpoint Services, so I don't know if this question is specific to that or is generic across all of the data services.)

    Is there an known Search method to be used with the DataManager that gets generated from the DSW?

    Here is what I would ideally want:
    public List<T> SearchEntities<T>(int startIndex, int count, T searchParameters)

    Essentially we provide the method with the start index/count for paging (if we want) and then we also provide an instance of the object that we're searching ("searchParameters"). This method would then iterate through all of the properties on the searchParameters object and if they're not equal to the default value, then it would filter by that. So imagine I had an object that looked like this:

    Person.Id,
    Person.ParentBusinessId,
    Person.Address,
    Person.City,
    Person.State,
    Person.Zip

    It would be trivial for me to have a client application (in my case it would be my business tier) search through my people by various parameters. Finding all of the people in a business or all of the people in a business in a single state would be trivial. I realize complex search scenarios aren't handled by this but I would venture to say that this would cover HALF of all of my searches and seems like it should be doable with a single method that could be generated by the wizard. I'm working on writing this myself right now but if somebody else has this, it would be nice to see what they have.

    Thanks!
    -Shane
  2. Shane Milton
    Shane Milton avatar
    219 posts
    Member since:
    Dec 2003

    Posted 27 Feb 2010 Link to this post

    Oh, and of course one of my requirements are that this needs to work nicely for large sets of data. Imagine a table with a hundred million records or so. Of course this would in part depend upon the number of results I want back, the size of the objects, and database indexes, but I want to make sure as much is lazy-loaded as possible instead of getting back a resultset of millions and THEN querying it...
  3. DevCraft banner
  4. Shane Milton
    Shane Milton avatar
    219 posts
    Member since:
    Dec 2003

    Posted 01 Mar 2010 Link to this post

    Okay, so I spent a couple hours over the weekend looking at this and here is what I have so far. This is 100% untested but is going in the right direction, I think. Since the DataManager is a partial class, I added another file as a partial class with my custom code so regenerations of DataManager.cs doesn't hose my work. Here is my custom code with my SearchEntities method:

    DataManager.Custom.cs
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Linq.Dynamic; 
    using System.Text; 
    using Telerik.OpenAccess; 
     
    namespace Foo 
        public partial class DataManager 
        { 
            /// <summary> 
            /// Read All Entities. 
            /// </summary> 
            /// <typeparam name="T">Open Access entity type.</typeparam> 
            /// <param name="stratIndex">Start Index.</param> 
            /// <param name="count">Entities Count.</param> 
            /// <param name="searchParameters">Object containing search parameters. If a property's value should be ignored, then it should be set to the default value.</param> 
            /// <returns>All entities list of class type.</returns> 
            public List<T> SearchEntities<T>(int stratIndex, int count, T searchParameters) 
            { 
                var parameters = new List<KeyValuePair<stringobject>>(); 
     
                foreach (var item in searchParameters.GetType().GetProperties()) 
                { 
                    //try 
                    //{ 
                    // Get the stringvalue attributes 
                    var attributes = item.GetCustomAttributes( 
                        typeof (FieldAliasAttribute), false); 
     
                    if (attributes.Count() != 0) 
                    { 
                        var value = item.GetValue(item, null); 
     
                        // Makes sure the property is not the default value. 
                        // ! Cannot execute Equals(value, default((Type)variable)) - this does not compile! Using null converts this to 0 for value-types, so it works. 
                        if (!Equals(value, null)) 
                        { 
                            parameters.Add(new KeyValuePair<stringobject>(item.Name, value)); 
                        } 
                    } 
                    //} 
                    //catch 
                    //{ 
                    //    // Not sure what would happen here. 
                    //    continue; 
                    //} 
                } 
     
                var paramString = new StringBuilder(); 
                var paramValues = new ArrayList(); 
                for (var i = 0; i < parameters.Count; i++) 
                { 
                    if (i > 0) 
                    { 
                        paramString.Append(" and "); 
                    } 
                    paramString.Append(parameters[i].Key); 
                    paramString.Append(" = @"); 
                    paramString.Append(i.ToString()); 
     
                    paramValues.Add(parameters[i].Value); 
                } 
     
                try 
                { 
                    var results = scope.Extent<T>().Where(paramString.ToString(), paramValues); 
                    return results.ToList(); 
                } 
                catch (OpenAccessException ex) 
                { 
                    RollBackTransaction(scope); 
                    throw ex; 
                } 
            } 
        } 


    This is all of my custom code but you'll notice that it depends on the System.Linq.Dynamic namespace, which doesn't exist. This is something I found thanks to a blog post from ScottGu and you can download it here (or here for VB). In that download, though, there are TONS of other things. And since all I wanted was the Dynamic Linq stuff, I just extracted that out and put it into a single file in my codebase. (I've tried to attach just that file to here but as it's about 2300 lines, the forum isn't playing nicely with me with that.)

    This morning I'm going to work with this a bit more to refine it but I think this is one possible way to go with this. We'll see, though.

    Any feedback anybody has in the mean time would be very appreciated!
    -Shane

    P.S. I'm working in VS2010 RC against .NET 4.0 RC, so if something doesn't look right here to you or doesn't compile, that is probably why.
  5. Peter Bahaa
    Admin
    Peter Bahaa avatar
    26 posts

    Posted 02 Mar 2010 Link to this post

    Hello Shane Milton,

    The generic search method is a really good idea. We will add this functionality in the next release to give the developers more control over their data services. We will provide paging support for all generated services as well.


    Greetings,
    Peter Bahaa
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  6. Shane Milton
    Shane Milton avatar
    219 posts
    Member since:
    Dec 2003

    Posted 04 Mar 2010 Link to this post

    That would be great! Is there any chance the generated code could be shared here so we can manually "generate" it to put it to use for when it begins to be automatically generated for us? Or if nothing else, share the interface for it?

    Many thanks!!
    -Shane
  7. Peter Bahaa
    Admin
    Peter Bahaa avatar
    26 posts

    Posted 10 Mar 2010 Link to this post

    Hello Shane Milton,

    I am afraid the build that we are going to release soon will not contain the generic search method. First we will have to remove the generated code that uses reflection so it supports hosting servers with medium trust. But we will add this functionality in one of the following releases.

    Sincerely yours,
    Peter Bahaa
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  8. Guy
    Guy avatar
    19 posts
    Member since:
    Apr 2011

    Posted 16 May 2011 Link to this post

    Did Generic Search ever get implemented?
  9. A.Alexandrov
    Admin
    A.Alexandrov avatar
    25 posts

    Posted 17 May 2011 Link to this post

    Hi Shane Milton,

    Yes, in the generated DataManager class for Wcf EndPoint services we have added the following search functionality:

    public List<T> SearchEntities<T>(T searchParameters)

    Hope that helps.

    Regards,

    A.Alexandrov
    the Telerik team
    Q1’11 SP1 of Telerik OpenAccess is available for download; also available is the Q2'11 Roadmap for Telerik OpenAccess ORM.
Back to Top
DevCraft banner