2014-04-25 98 views
0

我试图从评级表中获得人的平均评分,我有以下代码。我伸出结果为PersonVm类Linq的平均查询和投影

public IEnumerable SrchArtisansByBSSLR(string q, int s = 0, int l = 0, double z = 0) 
    { 
     var list = from item in _entities.People 
        where item.Skill.SkillName == q && item.StateId == s && item.LGAId == l && item.Ratings.Any(g => g.RatingValue == z) 
        group item by item.PersonId into d 
        select new PersonVm 
        { 
         PersonId = d.Key, 
         Rating = d.Average(x=>x.Ratings.Any(y=>y.RatingValue)), 
         LastName = item.LastName, 
         Skill = item.Skill.SkillName, 
         StateId = item.StateId, 
         LGAId = item.LGAId, 
         Address = item.Address, 
         Email = item.Email, 
         ImageSource = @"\Photos\" + item.ImageSource, 
         RegDate = item.RegDate      
        }; 
     return list;     
    } 

我收到以下错误

无法转换lambda表达式的委托类型“System.Func”,因为在一些块的返回类型不隐式转换为委托返回类型

不能隐式转换类型'double?' to'bool'ArtsHub.DataLayer

请问我的代码获得平均值有什么问题?

+0

你可以尝试'等级= d.Ratings.Average()'' – Yahya

+0

。任何()'返回一个布尔值 - 你的意思是'。首先()'? – CodingIntrigue

+0

@Yahya我试过评级= d.Ratings.Average()它不能将它看作是一个可访问的成员 – pressharp

回答

0

.ToList()... .GroupBy(item => new ...之前引起你的数据在内存中先取出,并group by会在内存中完成,你可以比较这两个查询的执行时间。

var list = _entities.People 
      .Where(item => item.Skill.SkillName == q && 
          item.StateId == s && 
          item.LGAId == l && 
          item.Ratings.Any(g => g.RatingValue == z)) 
      .ToList() 
      .GroupBy(item => new 
      { 
       item.PersonId, 
       item.LastName, 
       item.Skill.SkillName, 
       item.StateId, 
       item.LGAId, 
       item.Address, 
       item.Email, 
       item.ImageSource, 
       item.RegDate 
      }) 
      .Select(d => new PersonVm() 
      { 
       PersonId = d.Key, 
       Rating = d.Average(x => x.Ratings.Any(y => y.RatingValue)), 
       LastName = d.Key.LastName, 
       Skill = d.Key.SkillName, 
       StateId = d.Key.StateId, 
       LGAId = d.Key.LGAId, 
       Address = d.Key.Address, 
       Email = d.Key.Email, 
       ImageSource = @"\Photos\" + d.Key.ImageSource, 
       RegDate = d.Key.RegDate 
      }) 
      .ToList(); 
+0

哦,太棒了,我我会很有洞察力地尝试。谢谢阿米尔... – pressharp

+0

你好阿米尔,试图这个了我得到一个错误(不能隐式转换类型双?布尔)在评级属性(评级= d.Average(x => x.Ratings.Any(y = > y.RatingValue)))然后我改变它到这个(Rating = d.Average(x => x.Ratings.Sum(y => y.RatingValue)),)。这有效,但返回平均返回的总和。请问你有什么建议,我试图绕过它,无济于事...谢谢 – pressharp

0

x=>x.Ratings.Any(y=>y.RatingValue)返回bool的结果,因为.Any()产生boolean结果类型,你需要获得一个lambda.Average(),其产生type相同类型Rating属性。

似乎Rating是一个double?所以你需要一个lambda被传递到.Average()它会返回一个double?double或东西可以转化为double?

我认为你需要这样的:

Rating = d.Average(x => x.Ratings.Sum(y => y.RatingValue)) 
+0

这看起来非常清晰,符合逻辑的眼睛和编译器。它的工作原理是,我更新了一些我想访问的其他属性的问题后,他们无法访问。是不是分组后我不能再次访问'item',你会推荐什么?谢谢... – pressharp

+0

你的问题不清楚。而不是我,其他人(在评论中)没有想到你的意思是如何访问项目已被分组......最后是关于你的问题,你包括的所有这些属性,每个'PersonId'都一样? –

+0

我的意思是你的回答很清楚,它修正了错误。谢谢。我所说的是,在我带来这些财产后,我无法使用它们。对于问题是,它们对于每个人都是一样的,只是我投射到PersonVm中,以便不会选择所有的列...再次感谢...... – pressharp

0

你需要将它们添加到group by

var list = from item in _entities.People 

      where item.Skill.SkillName == q && item.StateId == s && item.LGAId == l && item.Ratings.Any(g => g.RatingValue == z) 

      group item by new { 
       item.PersonId, 
       item.LastName, 
       item.Skill.SkillName, 
       item.StateId, 
       item.LGAId, 
       item.Address, 
       item.Email, 
       item.ImageSource, 
       item.RegDate 
      } into d 

      select new PersonVm 
      { 
       PersonId = d.Key, 
       Rating = d.Average(x => x.Ratings.Any(y => y.RatingValue)), 
       LastName = d.Key.LastName, 
       Skill = d.Key.SkillName, 
       StateId = d.Key.StateId, 
       LGAId = d.Key.LGAId, 
       Address = d.Key.Address, 
       Email = d.Key.Email, 
       ImageSource = @"\Photos\" + d.Key.ImageSource, 
       RegDate = d.Key.RegDate 
      }; 
return list; 
+0

非常感谢,完美的工作。我只是想知道,如果我使用它来搜索成千上万的行,这会对性能产生影响...... – pressharp

+0

特别是当您通过复杂对象对项目进行分组时,特别是“group by”操作较慢,在这种情况下,它更有效首先获取你的数据,然后在内存中分组,通过这种方式,你可以提高你的性能,并执行你的查询,我需要添加另一个帖子来写一个查询,首先获取数据,然后做组 –