7

私のアプリケーションでは、partitionkeyが定数であるが、rowkeyが字句範囲内にある必要があるすべてのエンティティを取得するクエリを作成するという一般的な出来事があります(たとえば、接頭辞で始まる行のみ):

//query to get all entities in partition "KnownPartition" where RowKey starts with "Prefix_"
CloudTableQuery<MyEntity> query =
    (from e in tableServiceContext.CreateQuery<MyEntity>(tableName)
     where e.PartitionKey == "KnownPartition"
           && e.RowKey.CompareTo("Prefix_") > 0
           && e.RowKey.CompareTo("Prefix`") <= 0 // ` is '_' + 1
     select e).AsTableServiceQuery();

StartsWithなどの文字列関数はこの種のクエリではサポートされていないため、CompareToを使用する必要があります。これは機能しますが、条件が読みにくく、何度も繰り返されます。したがって、この読みにくい条件で多くのクエリを作成する代わりに、それを「インライン化」する関数を作成したいと思います。

public static Boolean HasPrefix(this String rowKey, String prefix)
{
    return rowKey.CompareTo(prefix + '_') > 0 && rowKey.CompareTo(prefix + '`') <= 0;
}

CloudTableQuery<MyEntity> query =
    (from e in tableServiceContext.CreateQuery<MyEntity>(tableName)
     where e.PartitionKey == "KnownPartition" && e.RowKey.HasPrefix("Prefix")
     select e).AsTableServiceQuery();

しかし、これを実行すると、関数がサポートされていないという例外がAzureから発生します。サポートされるようにこれを書く方法はありますか?結局のところ、関数にラップされただけで、機能したクエリとまったく同じ条件を使用しています...

4

2 に答える 2

17

これがケビンの答えの一般化です。これは同じことを行いますが、Davidが元の質問で尋ねた特定のケースだけでなく、任意のプレフィックス文字列に対して機能します。

public static Expression<Func<MyEntity, bool>> HasPrefix(String prefix) 
{ 
    char lastChar = prefix[prefix.Length - 1];
    char nextLastChar = (char)((int)lastChar + 1);
    string nextPrefix = prefix.Substring(0, prefix.Length - 1) + nextLastChar;

    return e => e.RowKey.CompareTo(prefix) >= 0 && e.RowKey.CompareTo(nextPrefix) < 0;
}
于 2012-10-23T17:56:14.857 に答える
10

条件を関数に分割する場合、関数はブール値ではなく式ツリーを返す必要があります。LINQクエリ構文がこれをサポートするかどうかはわかりませんが、次のようにメソッド構文を使用してサポートできます。

public static Expression<Func<MyEntity, bool>> HasPrefix(String prefix) 
{ 
    return e => e.RowKey.CompareTo(prefix + '_') > 0 && e.RowKey.CompareTo(prefix + '`') <= 0;
}

CloudTableQuery<MyEntity> query =
    (from e in tableServiceContext.CreateQuery<MyEntity>(tableName)
    where e.PartitionKey == "KnownPartition"
    select e)
    .Where(HasPrefix("Prefix"))
    .AsTableServiceQuery();
于 2012-10-18T17:52:48.877 に答える