【问题标题】:Protobuf-net and genericsProtobuf-net 和泛型
【发布时间】:2010-06-21 10:29:23
【问题描述】:

我对 protobuf-net 和泛型的使用有疑问。

给定:

    [DataContract]
public class CacheData
{
    [DataMember(Order = 1)]
    public List<CacheLoadItem<int>> Foo;

    [DataMember(Order = 2)]
    public List<CacheLoadItem<int>> Bar;

    [DataMember(Order = 3)]
    public List<CacheLoadItem<int>> XXX;

    [DataMember(Order = 4)]
    public List<CacheLoadItem<string>> YYY;

    [DataMember(Order = 5)]
    public List<CacheLoadItem<int>> Other;

    [DataMember(Order = 6)]
    public List<CacheLoadItem<int>> Other2;

    [DataMember(Order = 7)]
    public List<CacheLoadItem<int>> Other3;

    [DataMember(Order = 8)]
    public List<CacheLoadItem<string>> EvenMore;

    [DataMember(Order = 9)]
    public List<CacheLoadItem<string>> AlmostThere;
}

[DataContract]
public class CacheLoadItem<V>
{
    [DataMember(Order = 1)]
    public int ID;

    [DataMember(Order = 2)]
    public string Name;

    [DataMember(Order = 3)]
    public V Value;
}

具有通用 int 列表的 CacheLoadItem 可以很好地序列化,但具有通用字符串列表的 CacheLoadItem 不会。

我认为这与通用列表首先被序列化有关。

具有通用字符串列表的 CacheLoadItem 包含正确数量的项目,但具有默认/空值。

有人知道为什么会这样吗?

【问题讨论】:

  • 哪个版本的protobuf-net?和平台? (常规.net?单声道?cf?Silverlight?)。我不知道这里有问题,但很乐意调查。
  • .NET 3.5 protobuf-net.dll 版本 1.0.0.282 我通过 ASP.MVC 公开协议缓冲区序列化对象,并在 Windows 窗体客户端中使用它们。
  • 我会尝试对我拥有的 dll 进行单元测试,并使用非打乱的属性名称。
  • 对于信息,我对 2.0.x(未完全发布)进行了测试,因为这是我在本地拥有的 - 但如果测试在 1 上失败,我会感到惊讶(并且非常感兴趣) .x

标签: c# protocol-buffers protobuf-net


【解决方案1】:

好的,肯定是Entity Framework相关的。

CacheData 是使用 LINQtoEF 提取的。

喜欢:

                        using (var myDatabase = new MyDatabase(entityBuilder.ToString()))
        {
            result.A = (from a in myDatabase.ATable select new CacheLoadItem<int> { ID = a.ID, Name = a.Name, Value = a.Number }).ToList();
            result.B = (from b in myDatabase.BTable select new CacheLoadItem<string> { ID = b.ID, Name = b.Name, Value = b.Code }).ToList();
            result.C = (from c in myDatabase.CTable select new CacheLoadItem<int> { ID = c.ID, Name = c.Name, Value = c.ID }).ToList();
            result.D = (from d in myDatabase.DTable select new CacheLoadItem<int> { ID = d.ID, Name = d.Name, Value = d.Number }).ToList();
            result.E = (from e in myDatabaseETable select new CacheLoadItem<int> { ID = e.ID, Name = e.Name, Value = e.Number }).ToList();
            result.F = (from f in myDatabase.FTable select new CacheLoadItem<string> { ID = f.ID, Name = f.Name, Value = f.Number }).ToList();
            result.G = (from g in myDatabaseGTable select new CacheLoadItem<string> { ID = g.ID, Name = g.Name, Value = g.Code }).ToList();
            result.H = (from h in myDatabaseHTable select new CacheLoadItem<int> { ID = h.ID, Name = h.Name, Value = h.Number }).ToList();
            result.I = (from i in myDatabaseITable select new CacheLoadItem<int> { ID = i.ID, Name = i.Name, Value = i.Number }).ToList();
        }

不工作,但以下工作。

            using (var myDatabase = new MyDatabase(entityBuilder.ToString()))
        {
            result.A = (from a in myDatabase.ATable select a).ToList().Select(b => new CacheLoadItem<int> { ID = a.ID, Name = a.Name, Value = a.Number }).ToList();
            result.B = (from b in myDatabase.BTable select b).ToList().Select(b=>new CacheLoadItem<string> { ID = b.ID, Name = b.Name, Value = b.Code }).ToList();
            result.C = (from c in myDatabase.CTable select c).ToList().Select(c=> new CacheLoadItem<int> { ID = c.ID, Name = c.Name, Value = c.ID }).ToList();
            result.D = (from d in myDatabase.DTable select d).ToList().Select(d=> new CacheLoadItem<int> { ID = d.ID, Name = d.Name, Value = d.Number }).ToList();
            result.E = (from e in myDatabaseETable select e).ToList().Select(e=> new CacheLoadItem<int> { ID = e.ID, Name = e.Name, Value = e.Number }).ToList();
            result.F = (from f in myDatabase.FTable select f).ToList().Select(f => new CacheLoadItem<string> { ID = f.ID, Name = f.Name, Value = f.Number }).ToList();
            result.G = (from g in myDatabaseGTable select g).ToList().Select(g=> new CacheLoadItem<string> { ID = g.ID, Name = g.Name, Value = g.Code }).ToList();
            result.H = (from h in myDatabaseHTable select h).ToList().Select(h=> new CacheLoadItem<int> { ID = h.ID, Name = h.Name, Value = h.Number }).ToList();
            result.I = (from i in myDatabaseITable select i).ToList().Select(i=> new CacheLoadItem<int> { ID = i.ID, Name = i.Name, Value = i.Number }).ToList();
        }

不同的是我不在 LinqToEF 中进行转换,而是在 LINQtoObjects 中进行。

所以我猜是 EF 坏了?

【讨论】:

  • 在第一个纯 LinqToEF 样本中。数据在使用 ProtoBuf 序列化之前存在,但之后不存在。在使用 LintToObjects 的第二个中,数据在使用 ProtoBuf 序列化之前和之后都存在。
  • 好吧,我很乐意看一下,但有一个有趣的想法:我已经看到 LINQ-to-SQL 在序列化过程中丢弃惰性数据 - 由于回调 API,它只知道序列化。我可能想出一种方法(尤其是在“v2”中)来简单地跳过回调 API?但是,如果您找到了解决方法,它可能不值得吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 2022-06-22
  • 2011-02-06
  • 1970-01-01
相关资源
最近更新 更多