简体   繁体   中英

LINQ to Entities Not recognize System.String

I am getting this error that Linq doesn't recognize ToString . It work without the formatting style added like the dd/MM/yyyy . Is there a another way to do this?

ERROR

LINQ to Entities does not recognize the method 'System.String ToString

Code

var MeetingList = (from m in db.Meetings
join md in db.MeetingDates on m.MeetingId equals md.MeetingId
    select new Model.Meeting
    {
        MeetingId = m.MeetingId,
        MeetingDate = md.StartTime.Value.ToString("dd/MM/yyyy")
    }).ToList();

+1 to Crowcoder's & NetMage's comment: Formatting should be a UI concern, not a domain concern unless this is an API call. (In which case ISO format date "yyyy-MM-ddTHH:mm:ssZ" would be recommended)

To get around Linq to SQL limitations, you can opt to do a double-projection. This is expanding on NetMage's example, mainly to address considerations to employ filtering and guarding against potentially null data:

var meetingList = db.Meetings
    // TODO: Assuming a Where filter on what Meetings to include/exclude...
    .SelectMany(m => m.MeetingDates
        .Where(md => md.StartTime.HasValue) // Avoid null ref if StartTime can be null-able
        .Select(md => new { m.MeetingId, md.StartTime }))
    .ToList()
    .Select( x => new Model.Meeting
    {
        MeetingId = x.MeetingId,
        MeetingDate = x.StartTime.Value.ToString("dd/MM/yyyy")
    }).ToList();

This assumes that you have navigation properties set up between meetings and meeting dates. You can write it with explicit joins, but I highly recommend using navigation properties and letting EF work out the associations.

The first projection EF can convert safely to SQL and return the desired raw data. This is materialized with the ToList call. The second projection does the formatting against in-memory objects.

Double-projection should be used cautiously and avoid cases where simply slapping an extra ToList seems to fix the problem. For instance:

var meetingList = db.Meetings
    // TODO: Assuming a Where filter on what Meetings to include/exclude...
    .SelectMany(m => m.MeetingDates
        .Where(md => md.StartTime.HasValue))
    .ToList() // Materializes the list to memory so the below call will work... BAD.
    .Select( md => new Model.Meeting
    {
        MeetingId = md.MeetingId,
        MeetingDate = md.StartTime.Value.ToString("dd/MM/yyyy")
    }).ToList();

This would work, however the first projection would return entire MeetingDate entities to the server even though we only want a couple columns. If the later Select statement were to access further navigation properties, each of these iterations would trigger a potential lazy load call back to the database. It's important when considering a double-projection that the first projection that goes to SQL is as explicit as possible in terms of what data comes back.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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