Linq не поддерживает перевод на SQL - PullRequest
0 голосов
/ 26 декабря 2011

Я получаю сообщение об ошибке:

Метод 'System.Decimal getMeanRatingForGame (Int32)' не поддерживается перевод на SQL.

Для строки linq:

let R = getMeanRatingForGame(c.ID)

Вот линк полностью:

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 Ответ

1 голос
/ 26 декабря 2011

Вы достигли точки, где абстракция разрушается.

Поставщик LINQ переводит из LINQ в то, что базовое хранилище данных может понять (в данном случае SQL).

Как вы можете себе представить, в SQL нет функции getMeanRatingForGame, поэтому LINQ to SQL завершается ошибкой (как EF, LINQ to Oracle и т. Д.).

Одно из решений состоит в том, чтобы разбить ваш запрос на две (или более) части - ту, которая просто взаимодействует с SQL и с которой у SQL не возникнет проблем.

Используйте результат с другим запросом, который использует getMeanRatingForGame - получение LINQ to Objects, чтобы творить чудеса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...