使用实体框架返回数据实现Protobuf net v2

时间:2013-05-30 04:02:33

标签: .net linq entity-framework protocol-buffers protobuf-net

有人可以指出我的源代码有什么问题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.IO.Compression;
using System.Web.Services.Protocols;
using CCBProductionEntityModel;
using ConsoleDebug.NestleWebReference;
using ProtoBuf;

namespace ConsoleDebug
{
    class Program
    {

        static void Main(string[] args)
        {
            //This is where I get data from and store into a list
            CCBProductionEntities et = new CCBProductionEntities();
            List<GetNestleData_Result> results = et.GetNestleData(5).ToList();

            List<GetNestleData_Result> responseResults;

            using (var stream = new MemoryStream())
            {
                Serializer.Serialize(stream, results);

                using (var responseStream = new MemoryStream())
                {
                    responseResults = Serializer.Deserialize<List<GetNestleData_Result>>(responseStream);
                }
            }

            results = responseResults;

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < results.Count(); i++)
            {
                var result = results.ElementAt(i);
                sb.Append(result.AssetId + "\t" + result.DeviceId + "\t" + result.InstanceNumber + "\t" + result.Speed + "\t" + result.Heading + "\t" + result.DriverId + "\t" + result.PositionAge + "\t" + result.VehicleRegistrationNum + "\t" + result.GSMAddress + "\t" + result.Odometer + "\t" + result.Latitude + "\t" + result.Longitude + "\t" + result.Altitude + "\t" + result.IgnitionState);
            }
            Console.WriteLine(sb.ToString());
            Console.ReadLine();
        }
    }
}

尝试运行时,收到错误消息: 不期望类型,也不能推断合同:CCBProductionEntityModel.GetNestleData_Result

我尝试在任何地方搜索示例源代码,但有点难以找到一个好的和干净的,我是否必须在使用序列化程序之前定义一些东西?如何?谢谢!

2 个答案:

答案 0 :(得分:0)

GetNestleData_Result在哪里定义?这是你自己的代码吗?或者这是出自EF代码生成器?或...?

基本上,protobuf-net希望使用声明可用于序列化的数据协定的类型。特别是,因为protobuf妻子格式不包含成员名称(而只是字段编号),所以需要一种了解1 === Name等的方法有很多方法可以做到这一点。如果类型是您自己的代码,最简单的是添加属性 - 它将识别一些模式,例如:

[ProtoContract]
public class GetNestleData_Result {
    [ProtoMember(1)]
    public int SomeValue {get;set;}

    [ProtoMember(2)]
    public List<Foo> SomeMoreValues {get;set;}

    // etc
}

[DataContract]
public class GetNestleData_Result {
    [DataMember(Order=1)]
    public int SomeValue {get;set;}

    [DataMember(Order=2)]
    public List<Foo> SomeMoreValues {get;set;}

    // etc
}

如果您使用的是代码生成器,有时代码生成工具会很乐意添加DataContract / DataMember(用于WCF目的);但如果没有,则不希望编辑生成的文件。在这种情况下,还支持在单独的代码文件中的partial类中执行此操作 - 然后编译器将为您拼接:

[ProtoContract]
[ProtoPartialMember(1, "SomeValue")]
[ProtoPartialMember(2, "SomeMoreValues")]
partial class GetNestleData_Result {}

但是,如果类型完全在您的控件之外,并且不包含可用于确定顺序的任何属性,您还可以在代码中配置所有内容:

RuntimeTypeMode.Default.Add(typeof(GetNestleData_Result), false)
                       .Add("SomeValue", "SomeMoreValues");

会做同样的事情。

一旦序列化程序知道应该如何配置您的类型,它应该可以工作。

答案 1 :(得分:0)

谢谢Marc,你反应非常快:) 我通过装饰从Entity Framework Model生成的类来实现它:

public partial class GetNestleData_Result
{
    [ProtoMember(1)]
    public Nullable<int> AssetId { get; set; }
    [ProtoMember(2)]
    public long DeviceId { get; set; }
    [ProtoMember(3)]
    public Nullable<int> EventTime { get; set; }
    [ProtoMember(4)]
    public Nullable<short> InstanceNumber { get; set; }
    [ProtoMember(5)]
    public Nullable<short> Speed { get; set; }
    [ProtoMember(6)]
    public Nullable<short> Heading { get; set; }
    [ProtoMember(7)]
    public Nullable<int> DriverId { get; set; }
    [ProtoMember(8)]
    public Nullable<short> PositionAge { get; set; }
    [ProtoMember(9)]
    public string VehicleRegistrationNum { get; set; }
    [ProtoMember(10)]
    public string GSMAddress { get; set; }
    [ProtoMember(11)]
    public Nullable<int> Odometer { get; set; }
    [ProtoMember(12)]
    public Nullable<int> Latitude { get; set; }
    [ProtoMember(13)]
    public Nullable<short> Altitude { get; set; }
    [ProtoMember(14)]
    public Nullable<int> Longitude { get; set; }
    [ProtoMember(15)]
    public string IgnitionState { get; set; }
}