locked
trying to query using custom comparer RRS feed

  • Question

  • Hey, 

    I'm trying to query an Azure Storage Table using a custom RowKey comparer that basically splits the RowKey and compares each
    string separately (in order to get rows by only as part of the key matching,with out knowing the amount of parts the key has).


    I've tried the following but got an exception of "The expression value is not supported".

    // the actual query
    var q = from row in DataContext.CreateQuery<WorkItem>(TableName)
                                where CustomCompare(p_strRowPK,entity.RowKey)
                                select row ;
    
    // and the compare method
    private bool CustomCompare(string p_strFilterRowKey, string p_strTestedRowKey)
                {
                    string[] arrFilterValues = p_strFilterRowKey.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    string[] arrTestedValues = p_strFilterRowKey.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
    
                    int intEqualityCounter = 0;
    
                    if (arrFilterValues.Length == arrTestedValues.Length)
                    {
                        for (int intCurrentIndex = 0; intCurrentIndex < arrTestedValues.Length; intCurrentIndex++)
                        {
                            // They are either equal or the filter is empty for a certain value
                            if (arrFilterValues[intCurrentIndex] != string.Empty || arrTestedValues[intCurrentIndex] == arrFilterValues[intCurrentIndex])
                            {
                                intEqualityCounter++;
                            }
                        }
                    }
                    
                    return intEqualityCounter == arrFilterValues.Length && intEqualityCounter == arrTestedValues.Length;
                }



    Is there an easy way to make this work, or do i have to do this explicitly ?

    Friday, April 20, 2012 11:52 AM

Answers

  • Composite partition keys or row keys is not supported in the manner suggested by your implementation. In this case, the LINQ query cannot be translated to a query string suitable for Azure table storage. In the case for a composite key, you query should be something like RowKey >= “ xxx“ && RowKey <=  “yyy” where “xxx” and “yyy” are sub keys. So, yes you need to do this explicitly.

    I have written an alternate Azure table storage client, Lucifure Stash, which supports many abstractions including composite keys. Lucifure Stash also supports large data columns > 64K, arrays & lists, enumerations, out of the box serialization, user defined morphing, public and private properties and fields and more.
    It is available free for personal use at http://www.lucifure.com  or via NuGet.com.
    • Marked as answer by Arwind - MSFT Thursday, April 26, 2012 9:14 AM
    Friday, April 20, 2012 4:13 PM

All replies

  • Hi,

    Your Linq query is formatted wrongly I think.

    var q = from row in DataContext.CreateQuery<WorkItem>(TableName)
                
    where CustomCompare(p_strRowPK,row.RowKey)
                
    select row;

    would be equal to:

    var q = from row in DataContext.CreateQuery<WorkItem>(TableName)
                
    where true         
               
    select row ;

    This is not a valid Linq query. I think you should write something like:

    var q = from row in DataContext.CreateQuery<WorkItem>(TableName)
              
    where row.RowKey.CustomCompare(p_strRowPK) == true        
               
    select row ;

    You'll have to make ann extension method of the CustomCompare method for the String type of course:

    public static bool CustomCompare(this string p_strTestedRowKey, string p_strFilterRowKey)
               
    {
                   
    string[] arrFilterValues = p_strFilterRowKey.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                   
    string[] arrTestedValues = p_strFilterRowKey.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

                   
    int intEqualityCounter = 0;

                   
    if (arrFilterValues.Length == arrTestedValues.Length)
                   
    { for (int intCurrentIndex = 0; intCurrentIndex < arrTestedValues.Length; intCurrentIndex++)
                       
    {
                           
    // They are either equal or the filter is empty for a certain value
                           
    if (arrFilterValues[intCurrentIndex] != string.Empty || arrTestedValues[intCurrentIndex] == arrFilterValues[intCurrentIndex])
                           
    {
                                intEqualityCounter
    ++;
                           
    }
                       
    }
                   
    }
                   
                   
    return intEqualityCounter == arrFilterValues.Length && intEqualityCounter == arrTestedValues.Length;
               
    }


    With regards,

    Patriek

    www.patriekvandorp.net


    If this reply is of help to you, please don't forget to mark it as an answer.

    Friday, April 20, 2012 12:37 PM
  • Hey, That's not the problem.
    I get a runtime exception that the following message

    The expression value CustomCompare("10101", [10007].RowKey) is not supported

    which leads me to think that somehow linq fails to parse the query

    Friday, April 20, 2012 1:07 PM
  • Composite partition keys or row keys is not supported in the manner suggested by your implementation. In this case, the LINQ query cannot be translated to a query string suitable for Azure table storage. In the case for a composite key, you query should be something like RowKey >= “ xxx“ && RowKey <=  “yyy” where “xxx” and “yyy” are sub keys. So, yes you need to do this explicitly.

    I have written an alternate Azure table storage client, Lucifure Stash, which supports many abstractions including composite keys. Lucifure Stash also supports large data columns > 64K, arrays & lists, enumerations, out of the box serialization, user defined morphing, public and private properties and fields and more.
    It is available free for personal use at http://www.lucifure.com  or via NuGet.com.
    • Marked as answer by Arwind - MSFT Thursday, April 26, 2012 9:14 AM
    Friday, April 20, 2012 4:13 PM