已经有一个开放的DataReader关联

时间:2013-05-31 10:42:22

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

您好,我正在制作这个自动完成搜索栏,其中包含标题,说明和category_id,但我需要在另一个表中的类别名称,所以我从我的广告表中取出类别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);
            }
        }

1 个答案:

答案 0 :(得分:1)

getAds是一个可以从阅读器中懒散地获取数据的可枚举序列 - 然后循环遍历它。然后,为每个执行第二次查询 - getCategory。这里重要的是getAds 仍在读取数据 - 所以是的,你有嵌套命令。

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

  • 重新构建查询以同时获取类别 ,一次性 - 避免嵌套查询和明显的N + 1问题
  • .ToList()的末尾添加getAds,以便热切地完成第一个查询
  • 启用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);