【问题标题】:How would I serialize a LINQ-to-SQL lazy list我将如何序列化 LINQ-to-SQL 惰性列表
【发布时间】:2008-11-05 20:10:28
【问题描述】:

我有一个 linq 查询,我试图将它放入一个可序列化的对象中以进行分布式缓存 (Velocity),但由于 LINQ-to-SQL 惰性列表而失败

像这样

  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 与 Rob Conery 在他的 MVC 店面中使用的类相同...

所有三个类都标记为可序列化(MemberBlogs、MemberBlogCategories、LazyList...有什么想法吗?

【问题讨论】:

    标签: asp.net asp.net-mvc linq-to-sql serialization


    【解决方案1】:

    如果您将它放在分布式缓存中,则需要完全避免使用 LazyList。然后,您可以围绕整个 LINQ 语句调用 .ToList(),如下所示:

    (from x select new MemberBlogs).ToList()
    

    这应该是可缓存的,因为它强制对查询进行评估。

    【讨论】:

      【解决方案2】:

      我只是在猜测,但我想说问题在于它正在序列化查询而不是结果;我不知道 LazyList 的实现是什么样的,但您可能可以添加一个 OnSerializing 方法,该方法在序列化之前实际执行查询;比如:

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

      这样您就可以保留延迟加载(对于任何不进入缓存的内容),但如果它确实命中缓存,它将执行 linq 查询并缓存结果。

      【讨论】:

        【解决方案3】:

        如果要缓存它,为什么要使用惰性列表?不要使用惰性列表,使用缓存,问题就会消失。

        【讨论】:

          【解决方案4】:

          我知道这是一篇旧帖子,但我遇到了同样的问题,因为我想执行我的 LazyList 并将它们放入 AppFabric 缓存中。我最终将一些自定义序列化逻辑放入 LazyList 类型中。

          第一部分现在看起来像这样:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-09-03
            • 1970-01-01
            相关资源
            最近更新 更多