微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将动态类与 TableEntityAdapter 一起用于 Azure 表存储

如何解决将动态类与 TableEntityAdapter 一起用于 Azure 表存储

我有以下代码行:

var entity = new TableEntityAdapter<object>(obj,partitionKey,id);

对象 obj 包含属性,当我保存到表存储时,这些属性不会被保存。我明白为什么,因为它们没有在 object 类中定义。

如何定义 TableEntityAdapter 在运行时使用的类?

更新

是的,我使用 ElasticTableEntity 解决了这个问题,如下所述 - 但是,我还发现现在有一个内置的 DynamicTableEntity,它是认的表结果。它用于相同的目的。

解决方法

我用这个 ElasticTableEntity 解决了

http://pascallaurin42.blogspot.com/2013/03/using-azure-table-storage-with-dynamic.html

public class ElasticTableEntity : DynamicObject,ITableEntity,ICustomMemberProvider // For LinqPad's Dump
{
    public ElasticTableEntity()
    {
        this.Properties = new Dictionary<string,EntityProperty>();
    }
    
    public IDictionary<string,EntityProperty> Properties { get; private set; }
 
    public object this[string key] 
    { 
        get
        {
            if (!this.Properties.ContainsKey(key))
                this.Properties.Add(key,this.GetEntityProperty(key,null));
 
            return this.Properties[key];
        }
        set
        {
            var property = this.GetEntityProperty(key,value);
            
            if (this.Properties.ContainsKey(key))
                this.Properties[key] = property;
            else
                this.Properties.Add(key,property);
        }
    }
    
    #region DynamicObject overrides
 
    public override bool TryGetMember(GetMemberBinder binder,out object result)
    {
        result = this[binder.Name];
        return true;
    }
 
    public override bool TrySetMember(SetMemberBinder binder,object value)
    {
        this[binder.Name] = value;
        return true;
    }
    
    #endregion
    
    #region ITableEntity implementation
    
    public string PartitionKey { get; set; }
 
    public string RowKey { get; set; }
 
    public DateTimeOffset Timestamp { get; set; }
 
    public string ETag { get; set; }
    
    public void ReadEntity(IDictionary<string,EntityProperty> properties,OperationContext operationContext)
    {
        this.Properties = properties;
    }
 
    public IDictionary<string,EntityProperty> WriteEntity(OperationContext operationContext)
    {
        return this.Properties;
    }
    
    #endregion
    
    #region ICustomMemberProvider implementation for LinqPad's Dump
    
    public IEnumerable<string> GetNames()
    {
        return new[] { "PartitionKey","RowKey","Timestamp","ETag" }
            .Union(this.Properties.Keys);
    }
    
    public IEnumerable<Type> GetTypes()
    {
        return new[] { typeof(string),typeof(string),typeof(DateTimeOffset),typeof(string) }
            .Union(this.Properties.Values.Select(x => this.GetType(x.PropertyType)));
    }
    
    public IEnumerable<object> GetValues()
    {
        return new object[] { this.PartitionKey,this.RowKey,this.Timestamp,this.ETag }
            .Union(this.Properties.Values.Select(x => this.GetValue(x)));
    }
    
    #endregion
    
    private EntityProperty GetEntityProperty(string key,object value)
    {
        if (value == null) return new EntityProperty((string)null);
        if (value.GetType() == typeof(byte[])) return new EntityProperty((byte[])value);
        if (value.GetType() == typeof(bool)) return new EntityProperty((bool)value);
        if (value.GetType() == typeof(DateTimeOffset)) return new EntityProperty((DateTimeOffset)value);
        if (value.GetType() == typeof(DateTime)) return new EntityProperty((DateTime)value);
        if (value.GetType() == typeof(double)) return new EntityProperty((double)value);
        if (value.GetType() == typeof(Guid)) return new EntityProperty((Guid)value);
        if (value.GetType() == typeof(int)) return new EntityProperty((int)value);
        if (value.GetType() == typeof(long)) return new EntityProperty((long)value);
        if (value.GetType() == typeof(string)) return new EntityProperty((string)value);
        throw new Exception("not supported " + value.GetType() + " for " + key);
    }
    
    private Type GetType(EdmType edmType)
    {
        switch (edmType)
        {
            case EdmType.Binary : return typeof(byte[]);
            case EdmType.Boolean : return typeof(bool);
            case EdmType.DateTime : return typeof(DateTime);
            case EdmType.Double : return typeof(double);
            case EdmType.Guid : return typeof(Guid);
            case EdmType.Int32 : return typeof(int);
            case EdmType.Int64 : return typeof(long);
            case EdmType.String : return typeof(string);
            default: throw new Exception("not supported " + edmType);
        }
    }
 
    private object GetValue(EntityProperty property)
    {
        switch (property.PropertyType)
        {
            case EdmType.Binary : return property.BinaryValue;
            case EdmType.Boolean : return property.BooleanValue;
            case EdmType.DateTime : return property.DateTimeOffsetValue;
            case EdmType.Double : return property.DoubleValue;
            case EdmType.Guid : return property.GuidValue;
            case EdmType.Int32 : return property.Int32Value;
            case EdmType.Int64 : return property.Int64Value;
            case EdmType.String : return property.StringValue;
            default: throw new Exception("not supported " + property.PropertyType);
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。