2010-06-21 3 views
2

У меня проблема с protobuf-net и использованием дженериков.Protobuf-net и generics

Дано:

[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; 
} 

CacheLoadItem с родовыми Int списков получить сериализации просто отлично, но CacheLoadItem с родовыми списками строк не делают.

Я думаю, что это связано с тем, какой общий список сначала сериализуется.

CacheLoadItem с полными строковыми списками содержит правильное количество элементов, но со значениями по умолчанию/null.

Кто-нибудь знает, почему это происходит?

+0

Какая версия protobuf-net? и платформа? (обычный .net? mono? cf? Silverlight?). Я не знаю о проблеме здесь, но буду счастливо исследовать. –

+0

Не удается воспроизвести локально: http://code.google.com/p/protobuf-net/source/browse/trunk/Examples/Issues/SO3083847.cs –

+0

.NET 3.5 Protobuf-net.dll версия 1.0.0.282 Im разоблачение протокола буферизует сериализованные объекты через ASP.MVC и потребляет их в Windows Form Client. –

ответ

0

Хорошо, это связано с инфраструктурой 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 нарушен?

+0

результат имеет тип CacheData –

+0

В первом примере с чистым LinqToEF. Данные есть до сериализации с ProtoBuf, но не после. Во втором с LintToObjects данные есть до и после сериализации с ProtoBuf. –

+0

Хорошо, я с радостью посмотрю, но интересная мысль: я видел LINQ-to-SQL падение ленивых данных во время сериализации - он знает только о сериализации из-за API обратного вызова. Возможно, я придумаю способ (особенно в «v2»), чтобы просто пропустить API обратного вызова? Но если вы нашли обходное решение, это может не стоить того? –