Linq平均查询和投影

时间:2014-04-25 10:02:58

标签: c# linq entity-framework linq-to-entities

我试图从评级表中获得人们的平均评分,我有以下代码。我将结果投影到PersonVm类

    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?'到了布尔' ArtsHub.DataLayer

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

3 个答案:

答案 0 :(得分:0)

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

似乎Ratingdouble?,因此您需要将lambda传递给.Average(),其返回double?double或某些东西可以转换为double?

我认为你需要这个:

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

答案 1 :(得分: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; 

答案 2 :(得分: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();