我有一个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;方法,这个方法不能 翻译成商店表达
答案 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();