我正在尝试使用EntityResolver
从Azure TableResult.Execute
中动态填充一个空对象,除非省略match.SetValue
调用,否则调试不会进入Test
方法。它抛出一个异常,说明下面的内容。实际的azure表请求很好,在debug中我可以看到列值等,我只需要将它映射到一个本地类中,最好使用泛型和反射。
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
只是我本地实体上的一个标记接口。
任何帮助都非常感谢。
发布于 2013-05-28 02:35:11
改变这个: match.SetValue(prop,storagePropsmatch.Name.Int32Value);
对此: match.SetValue(objectToReturn,storagePropsmatch.Name.Int32Value);
发布于 2013-08-20 06:23:43
这是一个相当长的方法,但它是有效的:
//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;
}
发布于 2014-11-16 17:00:56
在Azure Storage组装本身(Microsoft.WindowsAzure.Storage.dll)中有一个EntityResolver代表的实现,称为EntityUtility.ResolveEntityByType<T>
,您可以根据自己的需要对其进行调整。那个类是内部的,所以你必须反汇编dll,但有很多工具可以做到这一点(Reflector很棒,ILSpy是免费的)。
https://stackoverflow.com/questions/15427049
复制相似问题