Reputation: 9209
I have a linq query and I am trying to put that in to a serializable object for a distributed caching (Velocity) but its failing due to a LINQ-to-SQL lazy list
like 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 is the same class Rob Conery uses in his MVC storefront...
all three classes are marked serializable (MemberBlogs,MemberBlogCategories,LazyList... any ideas?
Upvotes: 6
Views: 1806
Reputation: 592
I know this is an old post but I had the same issue as I wanted to execute my LazyList and put them into the AppFabric Cache. I ended up putting some custom serialization logic into the LazyList type.
The first part now looks like this:
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;
}
}
Upvotes: 0
Reputation: 32575
I'm just guessing, but I'd say the problem is that it is serializing the query instead of the results; I don't know what the implementation of the LazyList looks like, but you can probably add an OnSerializing method that actually executes the query prior to serializing it; Something like:
[OnSerializing]
private void ExecuteLinqQuery(StreamingContext context)
{
if (!SomethingThatIndicatesThisLinqQueryHasNotBeenExecuted)
LinqVariable.ToList()
}
This way you get to keep the Lazy Load (for anything that doesn't go into your cache), but then also if it does hit the cache, it'll execute the linq query and cache the results.
Upvotes: 3
Reputation: 2503
If you are putting it in a distributed cache you will need to avoid the LazyList altogether. You can then call .ToList() around the whole LINQ statement as in:
(from x select new MemberBlogs).ToList()
This should then be cachable because it forces the queries to be evaluated.
Upvotes: 6
Reputation: 28322
If you're caching it why are you using a lazy list? Don't use a lazy list, use caching, and the problem goes away.
Upvotes: 2