MVC LINQ 未识别的方法

MVC LINQ Not recognised method

我有一个从 table 中提取数据的 linq 查询,我想在给定日期后将其转换为星期(例如,它是一年中的哪一周)。

和 GetWeekofYear 函数:

 private int GetWeekOfYear(DateTime d)
 {
     var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
     return cal.GetWeekOfYear(new DateTime(d.Year, d.Month, 1), System.Globalization.CalendarWeekRule.FirstDay, System.DayOfWeek.Sunday);
 }

在当前状态下,当我尝试测试它时(使用 Postman / Fiddler)我收到以下错误:

LINQ to Entities does not recognize the method 'Int32 GetWeekOfYear(System.DateTime)' method, and this method cannot be translated into a store expression

错误发生是因为 Linq2Sql 无法将 GetWeekOfYear 方法转换为 SQL。

尝试以下操作:

  • select 原始数据改为 QuestionaireDetailsDTO

    select new QuestionaireDetailsDTO() {
        DepartureDate = transport.DepartureDate 
    };
    
  • 将 getter 添加到 QuestionaireDetailsDTO 进行计算:

    public string Week => GetWeekOfYear(DepartureDate);
    

这样转换发生在内存中而不是数据库中。

如果 GetWeekOfYear 方法驻留在 DTO 使用者无法访问的项目中,请在 select 从数据库编辑 DTO 后添加一个后处理步骤。

foreach (var result in query) {
     result.Week = GetWeekOfYear(result.DepartureDate);
}

您可以使用 .AsEnumerable()

var query = from booking in context.BookingTables
                    join transport in context.TransportAllotments on booking.TransportAllotmentID equals transport.TransportAllotmentID
                    join passenger in context.Passengers on booking.BookingID equals passenger.BookingID
                    join result in context.QuestionaireResults on passenger.PassengerID equals result.PassengerID
                    join question in context.QuestionaireQuestions on result.QuestionaireQuestionID equals question.QuestionaireQuestionID
                    where transport.DepartureDate >= startDate && transport.DepartureDate <= endDate && booking.BookingID == id
                    .AsEnumerable()
                    select new QuestionaireDetailsDTO()
                    {
                        ID = booking.BookingID,
                        Date = transport.DepartureDate,
                        Question = question.QuestionText,
                        Week =  GetWeekOfYear(transport.DepartureDate) 

                    };

希望对您有所帮助。

据我所知,发生这种情况是因为 LinqToSQL 无法将您的方法转换为 SQL。 我认为@GeorgPatscheider 的回答不是最好的,因为您不应该因为数据访问层的某些特定机制而更改数据对象。 所以,@PhongDao 的回答更酷,但他的解决方案将从数据库下载太多字段。您可以这样更改代码:

var query = from booking in context.BookingTables
        join transport in context.TransportAllotments on booking.TransportAllotmentID equals transport.TransportAllotmentID
        join passenger in context.Passengers on booking.BookingID equals passenger.BookingID
        join result in context.QuestionaireResults on passenger.PassengerID equals result.PassengerID
        join question in context.QuestionaireQuestions on result.QuestionaireQuestionID equals question.QuestionaireQuestionID
        where transport.DepartureDate >= startDate && transport.DepartureDate <= endDate && booking.BookingID == id
        // select only fields which we need
        select new
            {
                ID = booking.BookingID,
                Date = transport.DepartureDate,
                Question = question.QuestionText,
                DepartureDate = transport.DepartureDate
            }
        // retrieve data from DB
        .ToArray()
        // create items which you need
        .Select(x=>
        new QuestionaireDetailsDTO()
        {
            ID = x.ID,
            Date = x.Date,
            Question = x.Question,
            Week = GetWeekOfYear(x.DepartureDate)
        })
        // forming results
        .ToArray();