Почему я получаю сообщение об ошибке «метод не поддерживает перевод в SQL»? - PullRequest
2 голосов
/ 02 декабря 2008

я получаю эту ошибку

{"Method 'System.DateTime ConvertTimeFromUtc(System.DateTime, System.TimeZoneInfo)' has no supported translation to SQL."}  

когда я пытаюсь выполнить это linq to sql

var query = from p in db.Posts
            let categories = GetCategoriesByPostId(p.PostId)
            let comments = GetCommentsByPostId(p.PostId)
            select new Subnus.MVC.Data.Model.Post
            {
                Categories = new LazyList<Category>(categories),
                Comments = new LazyList<Comment>(comments),
                PostId = p.PostId,
                Slug = p.Slug,
                Title = p.Title,
                CreatedBy = p.CreatedBy,
                CreatedOn = TimeZoneInfo.ConvertTimeFromUtc(p.CreatedOn, TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time")),
                Body = p.Body
            };
return query;

есть другое место, где я могу преобразовать дату в правильный формат, в настоящее время у меня есть макрос, который я храню в _global.spark fil, но это кажется неправильным

<macro name="DateAndTime" Date="DateTime">
# Date = TimeZoneInfo.ConvertTimeFromUtc(Date, TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time"));
${Date.ToString("MMMM d, yyyy")} at ${Date.ToString("hh:mm")}
</macro>
<macro name="Date" Date="DateTime">
# Date = TimeZoneInfo.ConvertTimeFromUtc(Date, TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time"));
${Date.ToString("MMMM d, yyyy")}
</macro> 

Обновление: Теперь я понимаю, где код не работает, но когда я его удаляю, я получаю ту же ошибку для этого кода

 public IQueryable<Subnus.MVC.Data.Model.Comment> GetCommentsByPostId(int postId)
    {
        var query = from c in db.Comments
                    where c.PostId == postId
                    select new Subnus.MVC.Data.Model.Comment
                    {
                        Body = c.Body,
                        EMail = c.EMail,
                        Date = c.CreatedOn,
                        WebSite = c.Website,
                        Name = c.Name
                    };

        return query;
    }

Ответы [ 2 ]

3 голосов
/ 02 декабря 2008

Linq-to-Sql не может переводить произвольные функции .net в SQL. Однако некоторые функции DateTime можно перевести, и полный список доступен здесь: -

http://msdn.microsoft.com/en-us/library/bb882657.aspx

В вашем примере, если вы вычисляете смещение времени вне проекции, вы можете добавить смещение к извлеченному «CreatedOn» DateTime, используя метод AddMinutes, который поддерживает перевод в SQL.

1 голос
/ 02 декабря 2008

LINQ-to-SQL переводит только подмножество операций - и он пытается (и не может) записать ConvertTimeFromUtc как TSQL. Некоторые операции имеют аналоги TSQL (dateadd / datediff / etc) - но не все. Вы можете сделать проекцию (выбрать), используя необработанное значение, и выполнять ConvertTimeFromUtc только тогда, когда у вас есть объект в памяти (через LINQ-to-Objects).

Например, вы можете создавать объекты, просто используя p.CreatedOn, а затем делать все остальное. Не идеал, но жизнь. LINQ-to-Entities претендует на лучшие варианты перевода, но значительно сложнее. В зависимости от вашего сценария LINQ-to-SQL также предлагает поддержку udf, которая иногда позволяет вам выгружать эти вещи в db - , если , есть способ записать его как udf - например, вы можете написать метод в контексте данных и пометить его как компонуемую функцию ([Function]), тогда что-то вроде:

 ...
    CreatedOn = ctx.MapDate(p.CreatedOn)
 ....

Который затем использовал бы TSQL из [Function], то есть что-то вроде:

....
    dbo.MapDate(t2.CreatedOn)
....
...