1

我正在制作这个包含标题、描述和 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);
            }
        }
4

1 回答 1

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);
于 2013-05-31T10:47:25.770 回答