MVC LINQ无法识别的方法

时间:2016-08-12 07:27:31

标签: c# entity-framework linq linq-to-entities

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

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 new QuestionaireDetailsDTO()
                        {
                            ID = booking.BookingID,
                            Date = transport.DepartureDate,
                            Question = question.QuestionText,
                            Week =  GetWeekOfYear(transport.DepartureDate) 

                        };

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无法识别方法&#39; Int32   GetWeekOfYear(的System.DateTime)&#39;方法,这个方法不能   翻译成商店表达

3 个答案:

答案 0 :(得分:3)

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

尝试以下方法:

  • 选择原始数据代替QuestionaireDetailsDTO

    select new QuestionaireDetailsDTO() {
        DepartureDate = transport.DepartureDate 
    };
    
  • 为执行计算的QuestionaireDetailsDTO添加一个getter:

    public string Week => GetWeekOfYear(DepartureDate);
    

这种转换发生在内存而不是数据库上。

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

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

答案 1 :(得分:2)

您可以使用.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) 

                    };

希望有所帮助。

答案 2 :(得分:0)

正如我所知,这是因为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();