0

我正在尝试使用EntityResolver从 Azure 动态填充一个空对象,除非您省略调用,否则TableResult.Execute调试不会进入该方法。它抛出一个异常,说明如下。实际的天蓝色表请求很好,在调试中我可以看到列值等,我只需要将它映射到本地类中,最好使用泛型和反射。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

改变这个:match.SetValue(prop, storageProps[match.Name].Int32Value);

对此:match.SetValue(objectToReturn, storageProps[match.Name].Int32Value);

于 2013-05-27T18:35:11.140 回答
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 回答
0

Azure 存储程序集本身 (Microsoft.WindowsAzure.Storage.dll) 中有一个 EntityResolver 委托的实现,称为EntityUtility.ResolveEntityByType<T>,您可以根据自己的需要进行调整。该类是内部的,因此您必须反汇编 dll,但是有很多工具可以做到这一点(Reflector 很棒,ILSpy 是免费的)。

于 2014-11-16T09:00:55.563 回答