MVC LINQ 无法识别的方法

Posted

技术标签:

【中文标题】MVC LINQ 无法识别的方法【英文标题】:MVC LINQ Not recognised method 【发布时间】:2016-08-12 07:27:31 【问题描述】:

我有一个从表中提取数据的 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 无法识别方法 'Int32 GetWeekOfYear(System.DateTime)' 方法,并且该方法不能 翻译成商店表达式

【问题讨论】:

您需要先将查询物化到内存中 - var query = (from booking ..... where .... ).ToList().Select(x => new QuestionaireDetailsDTO() .... ); 我已经通过在对象中设置一个 getter 来解决它,但我还有另一个问题。如何防止将某些对象属性序列化为 json 并且仅在需要时对其进行序列化?我已经尝试过 [IgnoreDataMember],但似乎并没有按照我的意愿去做。 @StephenMuecke 您需要提出一个新问题并提供相关详细信息。 【参考方案1】:

出现该错误是因为 Linq2Sql 无法将GetWeekOfYear 方法转换为 SQL。

尝试以下方法:

选择原始数据而不是QuestionaireDetailsDTO

select new QuestionaireDetailsDTO() 
    DepartureDate = transport.DepartureDate 
;

QuestionaireDetailsDTO 添加一个执行计算的getter:

public string Week => GetWeekOfYear(DepartureDate);

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

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

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

【讨论】:

【参考方案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) 

                    ;

希望对您有所帮助。

【讨论】:

【参考方案3】:

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

【讨论】:

我已经通过在对象中设置一个 getter 来解决它,但我还有另一个问题。如何防止某些对象属性的序列化为 json 并且仅在需要时对其进行序列化?我已经尝试过 [IgnoreDataMember],但似乎没有达到我想要的效果。 我认为应该是单独的问题。

以上是关于MVC LINQ 无法识别的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Spring Boot/MVC 资源设置可识别的内容/MIME 类型?

Swift:手势识别器无法识别的选择器发送到实例

“ValueError:无法识别的标记样式'hline'”。 Matplotlib plot() 和 scatter() 函数无法识别一堆标记

如何修复:“无法识别的令牌'无法识别':期待('true','false'或'null')”使用Horton schema-registry

用ACCESS数据库提示 无法识别的数据库格式

Subsonic 2.2 ASP.NET MVC 无法识别的配置部分