【问题标题】:How can I add datacontract to a type (xxxDataTable) which is created by a typed data set?如何将数据契约添加到由类型化数据集创建的类型 (xxxDataTable)?
【发布时间】:2013-02-26 14:32:14
【问题描述】:

我有一个类型化的数据集,我想将表(由 .net 创建)或行集合而不是对象(我将创建)或对象集合传递到客户端。 Silverlight 框架不支持 system.data.datatable。

【问题讨论】:

  • 好问题是答案的一半。如果框架不支持它是不可能的。如果框架中的类型不可用,WCF 将无济于事。
  • 让我做对了。你在服务端有一些TypedDataSet,你想让Silverlight在客户端自动生成Types,然后你想把服务端的TypedDataSet序列化成字节流,在客户端反序列化?
  • @ChuiTey 调用服务方法,通过服务引用返回服务引用中存在的类型的对象实例。我可以使用这些函数返回自定义类型的集合。我想作为类型化数据集类型返回。

标签: wcf silverlight datatable datacontract datamember


【解决方案1】:

您不需要将 datacontract 属性添加到您不拥有的类型。您可以实现 IDataContractSurrogate 以将客户端未知类型的实例替换为已知类型的实例(例如轻量级数据表 POCO)。

如果您使用代码优先方法,您将不会在类型化数据集类对象和您自己的序列化/反序列化 POCO 对象之间进行这种额外的投影复制操作(并且您可以完全控制数据对象类型 (POCO) )。

我发现使用 Json.Net 'any object to JObject' 转换器(非常快速且可自定义)作为转换为其他东西之前的第一步很有用:

public static class JsonExtensions
{   
    public static object Normalize(this JToken token)
    {
        var type = token.GetType();
        if (type == typeof(JObject))
        {
            return (token as JObject).OfType<JProperty>().ToDictionary<JProperty, string, object>(property => property.Name, property => property.Value.Normalize());
        }
        if (type == typeof(JProperty))
        {
            var property = token as JProperty;
            //return new DictionaryEntry(property.Name, property.Value.Normalize());
            return new KeyValuePair<string, object>(property.Name, property.Value.Normalize());
        }
        if (type == typeof(JValue))
        {
            return (token as JValue).Value;
        }
        if (type == typeof(JArray))
        {
            //return (token as JArray).OfType<JValue>().Select(value => value.Normalize()).ToArray();
            return (token as JArray).Select(value => value.Normalize()).ToArray();
        }
        throw new NotImplementedException();
        //return null;
    }
}

public class TestClass
{
    public string StringProperty { get; set; }
    public int IntProperty { get; set; }
    public TestClass RefProperty { get; set; }
}

private static string DataContractXmlSerialize<T>(T source)
{
    var serializer = new DataContractSerializer(source.GetType());
    using (var ms = new MemoryStream())
    {
        serializer.WriteObject(ms, source);

        return Encoding.UTF8.GetString(ms.ToArray());
    }
}

用法:

var test = new TestClass()
            {
                StringProperty = "StringProperty",
                IntProperty = int.MaxValue,
                RefProperty = new TestClass() { IntProperty = int.MinValue }
            };

var jObj = JObject.FromObject(test);
var dict = jObj.Normalize();

var serializedDict = DataContractXmlSerialize(dict);

如您所见 - 输出是 WCF 可序列化的(被序列化的标准字典生成的 xml 不是很好,但您可以使用自己的可序列化字典)

【讨论】:

  • 我在没有序列化的情况下传递数据,它工作得很好。我正在寻找在不为每个实体创建类的情况下传递对象的方法
  • 您可以实现将任何实体转换为字典层次集的通用方法
  • 我就是这么做的。我要做的是使“该字典中的对象”成为由类型化数据集创建的类型的实例。
  • 我的意思是深度递归转换——当每个非原始对象变成字典。您可以缓存某些类型的属性获取器以加快基于反射的转换。
  • 我不知道该怎么做。愿意分享一些链接吗?
【解决方案2】:

您根本无法在 Silverlight 客户端中使用 DataTable 的 ADO.NET 实现,但有替代方案。

不过,this blog post 有另一种 DataTable 实现,您可以对其进行序列化并在 Silverlight 中提供支持。

【讨论】:

  • 这类似于简单的数据表,但不是类型化的数据集“实体”类。
  • 我在没有序列化的情况下传递数据,它工作得很好。我正在寻找在不为每个实体创建类的情况下传递对象的方法
【解决方案3】:

如果您想访问 Silverlight 应用程序中的数据,您应该使用 RIA 服务。您应该创建自定义 DTO 对象并从 DataTable 行创建 DTO 对象列表并从 RIA 服务返回它。

您开始使用 RIA 服务,请关注 MSDN http://msdn.microsoft.com/en-us/library/ee707376(v=vs.91).aspx

【讨论】:

    猜你喜欢
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    相关资源
    最近更新 更多