How to access table storage entities without knowing the schema
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;
using System.Data.Services.Common;
using Microsoft.Samples.ServiceHosting.StorageClient;
using System.Xml.Linq;
using System.Xml;
namespace AccessTableStorageUsingGenericEntiry
{
class Program
{
static void Main(string[] args)
{
test a = new test();
a.TestGenericTable();
}
}
[DataServiceKey("PartitionKey", "RowKey")]
public class GenericEntity
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
Dictionary<string, object> properties = new Dictionary<string, object>();
internal object this[string key]
{
get
{
return this.properties[key];
}
set
{
this.properties[key] = value;
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, object> a in properties)
{
sb.AppendLine(a.Key + ":" + a.Value);
}
return sb.ToString();
}
}
class GenericEntityDataServiceContext : TableStorageDataServiceContext
{
public GenericEntityDataServiceContext(StorageAccountInfo accountInfo)
: base(accountInfo)
{
}
public IQueryable<GenericEntity> GenericEntities
{
get
{
return this.CreateQuery<GenericEntity>("GenericEntities");
}
}
}
public class test
{
public void TestGenericTable()
{
StorageAccountInfo account = new StorageAccountInfo(new Uri("http://127.0.0.1:10002/"), true, "devstoreaccount1", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==");
TableStorage table1 = TableStorage.Create(account);
var ctx = table1.GetDataServiceContext();
ctx.IgnoreMissingProperties = true;
ctx.ReadingEntity += new EventHandler<ReadingWritingEntityEventArgs>(OnReadingEntity);
//"Messages" is a table name in table storage
var customers = from o in ctx.CreateQuery<GenericEntity>("Messages") select o;
Console.WriteLine("Rows from '{0}'", "Messages");
foreach (GenericEntity entity in customers)
{
Console.WriteLine(entity.ToString());
}
}
public void OnReadingEntity(object sender, ReadingWritingEntityEventArgs args)
{
// TODO: Make these statics
XNamespace AtomNamespace = "http://www.w3.org/2005/Atom";
XNamespace AstoriaDataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
XNamespace AstoriaMetadataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
GenericEntity entity = args.Entity as GenericEntity;
if (entity == null)
{
return;
}
// read each property, type and value in the payload
var properties = args.Entity.GetType().GetProperties();
var q = from p in args.Data.Element(AtomNamespace + "content")
.Element(AstoriaMetadataNamespace + "properties")
.Elements()
where properties.All(pp => pp.Name != p.Name.LocalName)
select new
{
Name = p.Name.LocalName,
IsNull = string.Equals("true", p.Attribute(AstoriaMetadataNamespace + "null") == null ? null : p.Attribute(AstoriaMetadataNamespace + "null").Value, StringComparison.OrdinalIgnoreCase),
TypeName = p.Attribute(AstoriaMetadataNamespace + "type") == null ? null : p.Attribute(AstoriaMetadataNamespace + "type").Value,
p.Value
};
foreach (var dp in q)
{
entity[dp.Name] = GetTypedEdmValue(dp.TypeName, dp.Value, dp.IsNull);
}
}
private static object GetTypedEdmValue(string type, string value, bool isnull)
{
if (isnull) return null;
if (string.IsNullOrEmpty(type)) return value;
switch (type)
{
case "Edm.String": return value;
case "Edm.Byte": return Convert.ChangeType(value, typeof(byte));
case "Edm.SByte": return Convert.ChangeType(value, typeof(sbyte));
case "Edm.Int16": return Convert.ChangeType(value, typeof(short));
case "Edm.Int32": return Convert.ChangeType(value, typeof(int));
case "Edm.Int64": return Convert.ChangeType(value, typeof(long));
case "Edm.Double": return Convert.ChangeType(value, typeof(double));
case "Edm.Single": return Convert.ChangeType(value, typeof(float));
case "Edm.Boolean": return Convert.ChangeType(value, typeof(bool));
case "Edm.Decimal": return Convert.ChangeType(value, typeof(decimal));
case "Edm.DateTime": return XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.RoundtripKind);
case "Edm.Binary": return Convert.FromBase64String(value);
case "Edm.Guid": return new Guid(value);
default: throw new NotSupportedException("Not supported type " + type);
}
}
}
}
posted on 2009-02-11 14:45 Yang - Windows Azure 阅读(370) 评论(0) 编辑 收藏 举报