【问题标题】:Why do I get the "method has no supported translation to SQL" error?为什么我会收到“方法没有支持的 SQL 转换”错误?
【发布时间】:2008-12-01 22:35:34
【问题描述】:

我得到这个错误

{"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 文件中有一个宏,但这似乎是错误的

<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;
    }

【问题讨论】:

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


    【解决方案1】:

    Linq-to-Sql 无法将任意 .net 函数转换为 SQL。但是,可以翻译一些 DateTime 函数,并且可以在此处获得完整列表:-

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

    在您的示例中,如果您计算投影之外的时间偏移量,则可以使用支持转换为 SQL 的 AddMinutes 方法将偏移量添加到检索到的“CreatedOn”DateTime。

    【讨论】:

    • 要做到这一点,我需要知道我从数据库中挑选出来的时间,因为夏天并不总是 gmt+1,而是 gmt+2
    • 嗯,没错(!)。我觉得有办法解决这个问题,让我思考一下……
    【解决方案2】:

    LINQ-to-SQL 仅转换操作的子集 - 它尝试(并且失败)将 ConvertTimeFromUtc 写入 TSQL。有些操作有 TSQL 对应项(dateadd/datediff/etc)——但不是全部。您可能会选择使用原始值进行投影(选择),并且只有在内存中有对象后(通过 LINQ-to-Objects)才执行 ConvertTimeFromUtc。

    例如 - 您可以只使用 p.CreatedOn 创建对象,然后再完成其余的工作。不是理想,而是生活。 LINQ-to-Entities 声称有更好的翻译选项,但要复杂得多。根据您的场景,LINQ-to-SQL 还提供 udf 支持,有时 可以让您将这些东西卸载到数据库 - 如果 有一种方法可以将其编写为udf - 例如,您可以在数据上下文中编写一个方法,并将其标记为可组合函数 ([Function]),然后类似于:

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

    然后将使用来自[Function] 的 TSQL - 即类似:

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

    【讨论】:

    • 能否加个链接到如何使用[Function] i linq to sql datacontext
    • 在最简单的级别,只需将 UDF 拖到设计器上。要手动执行,请参见此处的简单示例:groups.google.com/group/…
    猜你喜欢
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 2019-12-05
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    相关资源
    最近更新 更多