简体   繁体   English

Linq中的SQL在SQL中没有受支持的翻译

[英]Method has no supported translation in SQL in Linq

I am trying to group by week in Linq. 我想在Linq一周分组。 I created helper method to define the week I want to group by but when running the code I get the error message: 我创建了帮助方法来定义我要分组的周,但是在运行代码时我收到错误消息:

{"Method 'Int32 GetWeekNumber(System.DateTime)' has no supported translation to SQL."} System.SystemException {System.NotSupportedException} {“Method'Int32 GetWeekNumber(System.DateTime)'没有支持的SQL转换。”} System.SystemException {System.NotSupportedException}

My Linq query: 我的Linq查询:

var data = from trans in _dbc.MyStuff
       where
           SqlMethods.Like(trans.SEGMENT2, "00601") && SqlMethods.Like(trans.SEGMENT4, "%")
           &&
           trans.CREATION_DATE >= new DateTime(2013, 01, 01) &&
           trans.CREATION_DATE <= new DateTime(2013, 12, 31)
       group trans by new
       {
           DateYear = (int?)trans.CREATION_DATE.Value.Year,
           DateMonth = (int?)trans.CREATION_DATE.Value.Month,
           DateWeek = (int?)WeekStuff.GetWeekNumber(trans.CREATION_DATE.Value)
       }
           into g
           orderby
               g.Key.DateYear,
               g.Key.DateMonth,
               g.Key.DateWeek
           select new
           {
               DateYear = g.Key.DateYear ?? 0,
               DateMonth = g.Key.DateMonth ?? 0,
               DateWeek = g.Key.DateWeek ?? 0,
               Value = g.Sum(p => p.BASE_TRANSACTION_VALUE) ?? 0,
               Count = g.Sum(p => p.PRIMARY_QUANTITY) ?? 0,
               DateCreated = g.Min(p => p.CREATION_DATE) ?? DateTime.Now,
               Department = g.Min(p => p.SEGMENT2)
           };

My Helper Method: 我的助手方法:

    public static int GetWeekNumber(DateTime date)
    {
        if (DateTimeFormatInfo.CurrentInfo != null)
        {
            Calendar cal = DateTimeFormatInfo.CurrentInfo.Calendar;
            return cal.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
        }
        return 0;
    }

Basically what I want to do is group also by week, how would I group using helper method (if I in fact will need a helper method to accomplish this)? 基本上我想要做的是按周分组,我如何使用辅助方法进行分组(如果我实际上需要辅助方法来实现这一点)?

LINQ tries to convert your code to sql and run it on the server. LINQ尝试将您的代码转换为sql并在服务器上运行它。 Your custom method can't be translated to SQL, that's normal. 您的自定义方法无法转换为SQL,这是正常的。 You'll probably have to populate the result of LINQ query first and then to group it additionally using LINQ to objects. 您可能必须首先填充LINQ查询的结果,然后使用LINQ to objects对其进行分组。

Step 1. Create a function in SQL that does the calculation needed (note this depends upon the @@DATEFIRST setting on your SQL server: 步骤1.在SQL中创建一个执行所需计算的函数(请注意,这取决于SQL Server上的@@DATEFIRST设置:

CREATE FUNCTION [dbo].[GetWeek](@dt datetime)
RETURNS int
BEGIN
    RETURN DATEPART( wk, @dt)
END

Step 2. In your data context class, add a function that does the same as your helper above, but marked as with the System.Data.Linq.Mapping.FunctionAttribute attribute: 步骤2.在您的数据上下文类中,添加一个与上面的帮助程序相同的函数,但标记为System.Data.Linq.Mapping.FunctionAttribute属性:

[Function(Name="dbo.GetWeek", IsComposable=true)]
public int GetWeekNumber([Parameter(Name="@dt", DbType="datetime")]DateTime date)
{
  Calendar cal = DateTimeFormatInfo.CurrentInfo.Calendar;
  return cal.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
}

The IsComposable=true indicates it can be used as part of other queries (ie it's a function, not a stored procedure). IsComposable=true表示它可以用作其他查询的一部分(即它是一个函数,而不是一个存储过程)。

Step 3. Now change your query to use dbc.GetWeekNumber instead of WeekStuff.GetWeekNumber . 步骤3.现在更改您的查询以使用dbc.GetWeekNumber而不是WeekStuff.GetWeekNumber

Alternatively, you could define the above method as: 或者,您可以将上述方法定义为:

[Function(Name="dbo.GetWeek", IsComposable=true)]
public int GetWeekNumber([Parameter(Name="@dt", DbType="datetime")]DateTime date)
{
  return (int)ExecuteMethodCall(this, (MethodInfo)MethodInfo.GetCurrentMethod(), date).ReturnValue;
}

That way, even when called outside of a query, it will hit the database rather than calculating it in the .NET code. 这样,即使在查询外部调用,它也会命中数据库,而不是在.NET代码中计算它。 This is slower (hitting a database for what we could calculate without it), but has the advantage of keeping the concept of first-day-of-week consistent between code that hits the database, and code that does not. 这个速度较慢(在没有它的情况下命中我们可以计算的数据库),但是具有在命中数据库的代码和不支持数据库的代码之间保持第一天的概念一致的优点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM