0

EntityResolverAzure から空のオブジェクトを動的に設定するために使用しようとしていますが、呼び出しを省略しない限りTableResult.Execute、デバッグはメソッドに入りません。以下を示す例外をスローします。実際の azure テーブル リクエストは問題なく、デバッグでは列の値などを確認できます。理想的にはジェネリックとリフレクションを使用して、それをローカル クラスにマップするだけです。Testmatch.SetValue

Method not found: 'System.Nullable`1<Int32> Microsoft.WindowsAzure.Storage.Table.EntityProperty.get_Int32Value()'.

問題は反省に関係していると思いますが、支援が必要です。

public T RetrieveRow(string partitionKey, string rowKey)
    {
        EntityResolver<IObTable> resolver = (pk, rk, ts, props, etag) => Test(props);
        CloudTable table = base.TableClient.GetTableReference(TableName);
        TableOperation operation = TableOperation.Retrieve<IObTable>(partitionKey, rowKey, resolver);
        TableResult retrievedResult = table.Execute(operation);
        return (T)retrievedResult.Result;
    }

public IObTable Test(IDictionary<string, EntityProperty> storageProps)
    {
        IObTable objectToReturn = (IObTable)Activator.CreateInstance(typeof(T));
        if (storageProps != null)
        {
            var emptyObjectProps = objectToReturn.GetType().GetProperties();
            foreach (var prop in storageProps)
            {
                PropertyInfo match = emptyObjectProps.FirstOrDefault(v=> v.Name==prop.Key);
                if (match!=null)
                {
                    if (match.PropertyType == typeof(Int32))
                    {
                        match.SetValue(prop, storageProps[match.Name].Int32Value);
                    }
                }
            }
        }
        return objectToReturn;
    }

IObTable私のローカルエンティティの単なるマーカーインターフェースです。

どんな助けでも大歓迎です。

4

3 に答える 3

1

これはかなり長い方法ですが、うまくいきます:

    //TEntity is any class derived from TableEnitity 
    public IEnumerable<TEntity> TestingGetPartitionEntities(string PartitionKey)
    {

        TableQuery<DynamicTableEntity> query = new TableQuery<DynamicTableEntity>().Where(
              TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, PartitionKey));

            EntityResolver<TEntity> resolver = (pk, rk, ts, props, etag) => 
            {
                //MUST create the 'reflected' instance in the 'EntityResolver', so resolver can create new instance foreach entity in query execution loop.
                TEntity objectToReturn = (TEntity)Activator.CreateInstance(typeof(TEntity));
                var objectProperties = objectToReturn.GetType().GetProperties();

                foreach (var prop in props)
                {
                    PropertyInfo match = objectProperties.FirstOrDefault(v => v.Name == prop.Key);
                    if (match != null)
                    {
                    if (match.PropertyType == typeof(Int32))
                    {
                        match.SetValue(objectToReturn, props[match.Name].Int32Value);
                    }
                    if (match.PropertyType == typeof(object))
                    {
                        match.SetValue(objectToReturn, props[match.Name].PropertyAsObject);
                    }
                    if (match.PropertyType == typeof(bool))
                    {
                        match.SetValue(objectToReturn, props[match.Name].BooleanValue);
                    }
                    if (match.PropertyType == typeof(byte[]))
                    {
                        match.SetValue(objectToReturn, props[match.Name].BinaryValue);
                    }
                    if (match.PropertyType == typeof(DateTimeOffset))
                    {
                        match.SetValue(objectToReturn, props[match.Name].DateTimeOffsetValue);
                    }
                    if (match.PropertyType == typeof(double))
                    {
                        match.SetValue(objectToReturn, props[match.Name].DoubleValue);
                    }
                    if (match.PropertyType == typeof(Guid))
                    {
                        match.SetValue(objectToReturn, props[match.Name].GuidValue);
                    }
                    if (match.PropertyType == typeof(int))
                    {
                        match.SetValue(objectToReturn, props[match.Name].Int32Value);
                    }
                    if (match.PropertyType == typeof(long))
                    {
                        match.SetValue(objectToReturn, props[match.Name].Int64Value);
                    }
                    if (match.PropertyType == typeof(string))
                    {
                        match.SetValue(objectToReturn, props[match.Name].StringValue);
                    }
                }
            }
            return objectToReturn as TEntity;
        };

        //This is the list that is returned to caller.
        List<TEntity> results = new List<TEntity>();
        foreach (TEntity entity in table.ExecuteQuery(query, resolver, null, null))
        {
            results.Add(entity as TEntity);
        }
        return results;
    }
于 2013-08-19T22:23:42.590 に答える
1

これを変更します: match.SetValue(prop, storageProps[match.Name].Int32Value);

これに: match.SetValue(objectToReturn, storageProps[match.Name].Int32Value);

于 2013-05-27T18:35:11.140 に答える
0

Azure Storage アセンブリ自体 (Microsoft.WindowsAzure.Storage.dll) には EntityResolver デリゲートの実装がありEntityUtility.ResolveEntityByType<T>、これはニーズに合わせて調整できます。そのクラスは内部であるため、dll を逆アセンブルする必要がありますが、それを行うための多くのツールがあります (Reflector は優れており、ILSpy は無料です)。

于 2014-11-16T09:00:55.563 に答える