Linq不支持转换为SQL

时间:2011-12-26 18:59:55

标签: c# asp.net linq linq-to-sql

我收到了错误:

  

方法'System.Decimal getMeanRatingForGame(Int32)'不受支持   转换为SQL。

对于linq Line:

let R = getMeanRatingForGame(c.ID)

这是完整的linq:

private static Game[] getTopRatedGamesDo(int Fetch, int CategoryID, int Skip)
{
    /**
        weighted rating (WR) = ((v ÷ (v+m)) × R + (m ÷ (v+m)) × C) x E
        where:
        R = average for the game
        v = number of votes for the game
        m = minimum votes required to be listed
        C = the mean weighted vote across the whole report
        E = Is not example game (example game = 0, not example = 1)
    */
    Game[] r;
    using (MainContext db = new MainContext())
    {
        // Mean
        decimal C = getMeanRatingForCat(CategoryID);

        // Min votes to be considered
        decimal m = Settings.GameVotesReqdForTopRatedBoards;

        // Entire games list
        if (CategoryID == 0)
        {
            var q = (from c in db.tblArcadeGames
                        let v = (decimal)db.tblArcadeGameVotes.Where(v => v.GameID == c.ID).Count()
                        let R = getMeanRatingForGame(c.ID)
                        let E = (c.CategoryID == 2 ? (decimal)0.1 : (decimal)1)
                        let WR = (((v / (v + m)) * R + (m / (v + m)) * C) * E)
                        where c.IsDeleted == false
                        && c.Approved == true
                        && c.TotalVotes >= Settings.GameVotesReqdForTopRatedBoards
                        orderby WR descending
                        select new { c, WR})
                .Skip(Skip)
                .Take(Fetch);

            r = new Game[q.Count()];
            int i = 0;
            foreach (var g in q)
            {
                r[i] = new Game(g.c, g.WR);
                i++;
            }
        }

这是抛出错误的函数:

/// <summary>
/// Gets the mean rating of a game.
/// </summary>
public static decimal getMeanRatingForGame(int GameID)
{
    /**
    Try multiplying each voter's rating base 10 logarithm of the rep of the voter,
        * then finding the weighted rating, then dividing by the mean of the base 10 logarithms
        * of the reps of the voters. Change the base from 10 to something like 2 if you want heavier weighting.
        * */
    decimal C = 0;
    using (MainContext db = new MainContext())
    {
        var q = (from c in db.tblArcadeGameVotes
                    where c.GameID == GameID
                let UserWeighting = (decimal)Math.Log((double)db.tblProfiles.Where(u => u.UserID == c.UserID).Single().Reputation, 10)
                let WeightedVote = UserWeighting * (decimal)c.Score
                select new { UserWeighting, WeightedVote });

        decimal AverageUserWeighting = (decimal)q.Sum(c => c.UserWeighting) / (decimal)q.Count();
        decimal AverageWeightedVote = (decimal)q.Sum(c => c.WeightedVote) / (decimal)q.Count();

        C = AverageWeightedVote / AverageUserWeighting;
    }
    return C;
}

我不允许在这样的linq语句中使用函数吗?

1 个答案:

答案 0 :(得分:1)

你正在达到抽象崩溃的程度。

LINQ提供程序从LINQ转换为底层数据存储可以理解的东西(在本例中为SQL)。

可以想象,SQL没有getMeanRatingForGame函数,因此LINQ to SQL失败(就像EF,LINQ to Oracle等......)。

一种解决方案是将您的查询分成两个(或更多)部分 - 一个只与SQL交互并且SQL不会出现问题。

将结果与另一个使用getMeanRatingForGame的查询一起使用 - 让LINQ to Objects发挥其魔力。