Linq

2010-07-17 72 views
3

的嵌套选择top 1在解决这一问题时存在一些问题。Linq

选择*,如照片来自鸡(选择chicken_photo顶部1 chicken_nr其中鸡=代码以便通过[排序])

码是在表鸡列

基本上获得封面照片查看这鸡。

为了使它更清晰,我希望它从表鸡返回多行。但只有一个来自chicken_photo的条目。

var q = from chicken in data.chickens 
        join photos in data.chicken_photos 
        on chicken.Code equals photos.chicken      
        where chicken.Lang==lang && chicken.photographer_nr == nr 
        group chicken by new  {chicken.photographer,photos.Photograph_Nr,chicken.Title,chicken.Code}    
+2

鸡单打网站? – 2010-07-17 08:48:43

+0

实际上它是为鸡农做杂交,所以我猜,是的。 – hreinn1000 2010-07-17 08:49:42

回答

7

这的确可以做到这样的,它导致只有一个SQL查询下方。

如果您执行了针对实体框架编写的子查询,那么Linq查询将成为单个SQL查询。

var q = from chicken in data.chickens 
      where chicken.photographer_nr == nr && chicken.Lang == lang 
      select new 
      { 
       chicken.photographer, 
       chicken.Code, 
       chicken.Title, 
       Photo = (from cp in data.chicken_photos 
         where cp.chicken == chicken.Code 
         orderby cp.Sort 
         select cp.Photograph_Nr).FirstOrDefault() 
      }; 

如果你的表有合适的主键和外键关系,并在实体框架适当的导航关联,那么你也可以达到相同的结果是这样的:

var q = from chicken in data.chickens 
      where chicken.photographer_nr == nr && chicken.Lang == lang 
      select new 
      { 
       chicken.photographer, 
       chicken.Code, 
       chicken.Title, 
       Photo = c.chicken_photos.Select(cp => cp.Photograph_Nr).FirstOrDefault() 
      }; 

最后,留下完全一致和仅使用拉姆达表达式:

var q = data.chickens 
     .Where(c => chicken.photographer_nr == nr && chicken.Lang == lang) 
     .Select(c => new 
      { 
       c.photographer, 
       c.Code, 
       c.Title, 
       Photo = c.chicken_photos.Select(cp => cp.Photograph_Nr).FirstOrDefault() 
      } 
     ); 

我宁愿依靠实体导航,因为它迫使开发人员创建正确的导航实体框架中的联系和数据库中正确的外键关系。这几乎总是会导致优化下面的SQL。

这不总是取决于开发者如何构建数据库,因此您可能必须坚持第一种方法并自己编写子选择。

0
var photo = (from c in chicken_photo where c.code = chicken orderby c.sort select c.chicken_nr).Take(1).SingleOrDefault(); 

你真的应该充实你的问题更多...

+0

嗯,我想多个鸡,所以我得到多行,但只检索chicken_photo一个条目 – hreinn1000 2010-07-17 08:51:27

3

我想通了。

非常明显的实际,太明显了:)

var q = from chicken in data.chickens 
       where chicken.photographer_nr == nr && lang == chicken.Lang 
       select new { chicken.photographer, chicken.Code, chicken.Title,Photo = (from b in data.chicken_photos where b.chicken==chicken.Code orderby b.Sort select b.Photograph_Nr).FirstOrDefault() }; 
+1

采取(1)是多余的。 First()将返回序列中的第一个值,无论该序列是否包含一个或多个值。请注意,如果没有照片,它会抛出,如果您想避免这种情况,请使用FirstOrDefault()。 – jeroenh 2010-07-17 13:44:14

+0

谢谢,我更新了答案,以反映这种更好的做法,虽然在我的情况下照片总是填充 – hreinn1000 2010-07-18 09:45:38

+0

不确定如果这是好的编码,但如果查询返回100个条目,这意味着100个连接到数据库顶部1 存储过程可能是这里的方式。 – hreinn1000 2010-07-18 09:48:26