【问题标题】:There is already an open DataReader associated已经有一个打开的 DataReader 关联
【发布时间】:2013-05-31 10:42:21
【问题描述】:

我正在制作这个包含标题、描述和 category_id 的自动完成搜索栏,但我需要另一个表中的类别名称,所以我从我的 ads 表中取出类别 id 并使用我知道的类别中的表检查 id我需要先关闭与数据库的连接,然后才能创建新的连接,所以我需要另一种方法。

public class SetGetAds
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string Category { get; set; }
    }

using (var db = new myProjectEnt())
        {
            var getAds = (from a in db.ads where a.title.Contains(searchQuery) select new { a.title, a.description, a.categories_id }).Take(15);

            var ads = new List<SetGetAds>();

            foreach (var setAds in getAds)
            {
                var getCategory = (from c in db.ads where c.title.Equals(setAds.categories_id) select new { c.title }).SingleOrDefault();

                ads.Add(new SetGetAds { Title = setAds.title, Description = setAds.description, Category = getCategory.title });

                var jsonString = new JavaScriptSerializer();
                return jsonString.Serialize(ads);
            }
        }

【问题讨论】:

    标签: c# asp.net web-services entity


    【解决方案1】:

    getAds 是一个可枚举的序列,它懒洋洋地从阅读器那里获取数据——然后你循环它。然后,对于每个,您正在执行第二个查询 - getCategory。这里重要的是 getAds 仍在读取数据 - 所以是的,你有嵌套命令。

    选项(按优先顺序,最高 = 首选):

    • 重组查询以一次性同时获取类别 - 避免嵌套查询和明显的 N+1 问题
    • getAds后面加一个.ToList(),急切完成第一个查询
    • 启用 MARS 以便允许进行嵌套查询

    N+1 问题通常是性能问题的根源;我个人希望以一种避免这种情况的方式编写此查询,例如:

    var ads = (from a in db.ads
               where a.title.StartsWith(searchQuery)
               join c in db.ads on a.categories_id equals c.title
               select new { a.title, a.description, a.categories_id,
                           category = c.title }).Take(15);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多