2008-11-05 4 views
6

Ich habe eine Linq-Abfrage und ich versuche, das in einem serialisierbaren Objekt für eine verteilte Caching (Velocity), aber seine aufgrund einer LINQ-zu-SQL-Fehler faul ListeWie würde ich eine LINQ-zu-SQL-faul-Liste serialisieren

wie so

return from b in _datacontext.MemberBlogs 
        let cats = GetBlogCategories(b.MemberBlogID) 
        select new MemberBlogs 
        { 
         MemberBlogID = b.MemberBlogID, 
         MemberID = b.MemberID, 
         BlogTitle = b.BlogTitle, 
         BlogURL = b.BlogURL, 
         BlogUsername = b.BlogUsername, 
         BlogPassword = b.BlogPassword, 
         Categories = new LazyList<MemberBlogCategories>(cats) 
        }; 

LazyList ist die gleiche Klasse Rob Conery in seinem MVC Storefront verwendet ...

allen drei Klassen sind serialisierbar markiert (MemberBlogs, MemberBlogCategories, LazyList ... jeder Ideen?

Antwort

6

Wenn Sie es in einen verteilten Cache stellen, müssen Sie die LazyList insgesamt vermeiden. Sie können dann rufen .ToList() um die ganze LINQ-Anweisung wie in:

(from x select new MemberBlogs).ToList() 

Dies sollte dann cachable sein, weil es die Abfragen zwingt ausgewertet werden.

2

Wenn Sie es zwischenspeichern, warum verwenden Sie eine faule Liste? Verwenden Sie keine faule Liste, verwenden Sie Zwischenspeichern, und das Problem verschwindet.

3

Ich rate nur, aber ich würde sagen, das Problem ist, dass es die Abfrage serialisiert anstelle der Ergebnisse; Ich weiß nicht, wie die Implementierung der LazyList aussieht, aber Sie können wahrscheinlich eine OnSerializing-Methode hinzufügen, die die Abfrage vor der Serialisierung tatsächlich ausführt. Etwas wie:

[OnSerializing] 
private void ExecuteLinqQuery(StreamingContext context) 
{ 
    if (!SomethingThatIndicatesThisLinqQueryHasNotBeenExecuted) 
     LinqVariable.ToList() 
} 

Auf diese Weise kann die Lazy Load zu halten bekommen (für alles, was nicht in den Cache nicht gehen), dann aber auch, wenn es um den Cache nicht getroffen, es wird die Linq-Abfrage ausführen und cache die Ergebnisse.

0

Ich weiß, das ist ein alter Beitrag, aber ich hatte das gleiche Problem, wie ich meine LazyList ausführen und sie in den AppFabric Cache setzen wollte. Ich habe schließlich eine benutzerdefinierte Serialisierungslogik in den LazyList-Typ eingefügt.

Der erste Teil sieht nun wie folgt aus:

public class LazyList<T> : IList<T>, ISerializable 
{ 

    public LazyList() 
    { 
     this.query = new List<T>().AsQueryable(); 
    } 

    public LazyList(SerializationInfo info, StreamingContext context) 
    { 
     try { 
      this.inner = (List<T>)info.GetValue("InnerList", typeof(List<T>)); 
     } 
     catch (Exception ex) 
     { 
      this.inner = null; 
     } 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     if (this.inner != null) 
      info.AddValue("InnerList", this.inner.ToList()); 
    } 

    public LazyList(IQueryable<T> query) 
    { 
     this.query = query; 
    } 

    public LazyList(List<T> l) 
    { 
     inner = l; 
    } 
}