0

When I am calling GetClosestStartDate it is popingup the following message Additional information:

LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression. I also tried by removing ToString from "TT.Startdate.Value.ToString()" and Changing "string CStartdate { get; set; } to DateTime CStartdate { get; set; }"

class Class_CourseStartdate
{
    public string CStartdate { get; set; }
    public int TimeTableID { get; set; }
}

   public List<Class_CourseStartdate> GetClosestStartDate(DateTime CoeStartdate)
   {
       return (from TT in _er.TimeTables
               where TT.Startdate == CoeStartdate
               select new Class_CourseStartdate 
               { CStartdate = TT.Startdate.Value.ToString() ,
                 TimeTableID = TT.TimeTableID 
               }
               ).ToList();
   }
2
  • Why is CStartdate a string? Commented Apr 9, 2014 at 7:25
  • Basically you can remove .ToString() from linq. Change you property type as datetime in your class. And convert your datetime object to string where you use it. Commented Apr 9, 2014 at 7:26

4 Answers 4

2

The simplest approach is to fetch just the data you want in the part that's translated into SQL, and then do the rest locally:

public List<Class_CourseStartdate> GetClosestStartDate(DateTime coeStartdate)
{
    return _er.TimeTables
              .Where(tt => tt.Startdate == coeStartdate)
              .Select(tt => new { tt.Startdate, tt.TimeTableID })
              .AsEnumerable() // Do the rest locally
              .Select(tt => new Class_CourseStartdate 
              { 
                   CStartdate = tt.Startdate.Value.ToString() ,
                   TimeTableID = tt.TimeTableID 
              }
              .ToList();
}

Note that I've stopped using a query expression here, as it becomes ugly when you need to then call methods on it - and all you're doing is a simple Where and Select. Query expressions are most useful when they involve transparent identifiers, e.g. in joins.

Next up, I would notice that we're already checking that tt.Startdate is equal to the date we've passed in - so why bother fetching it?

public List<Class_CourseStartdate> GetClosestStartDate(DateTime coeStartdate)
{
    return _er.TimeTables
              .Where(tt => tt.Startdate == coeStartdate)
              .Select(tt => tt.TimeTableID)
              .AsEnumerable() // Do the rest locally
              .Select(tid => new Class_CourseStartdate 
              { 
                   CStartdate = coeStartDate.ToString() ,
                   TimeTableID = tid
              }
              .ToList();
}

Or possibly just change the method to return timetable IDs, given that that's really what it's doing. I'd change the method name too:

public List<int> GetTimeTableIdsForStartDate(DateTime coeStartdate)
{
    return _er.TimeTables
              .Where(tt => tt.Startdate == coeStartdate)
              .Select(tt => tt.TimeTableID)
              .ToList();
}

Even if you do stick with Class_CourseStartdate I would change the CStartdate property to be just DateTime rather than string - avoid using strings in your models unless you really, really have to.

Additionally, your naming currently feels like it's all over the place - Startdate should be StartDate everywhere, you should drop the C and Class_ prefixes, etc.

Sign up to request clarification or add additional context in comments.

7 Comments

+1 Since yours is now the earliest answer using IQueryable.AsEnumerable msdn.microsoft.com/en-us/library/bb335435(v=vs.110).aspx
@Jodrell: It's actually Enumerable.AsEnumerable, but hey :)
@user3513192, I whole heartedly agree with the comments on naming and class design.
@Jodrell: Yup, from my obviously-biased perspective, that's a much better reason for upvoting my answer than just timing ;)
I was trying to distinguish from DataTableExtensions.AsEnumerable() which obviously doesn't apply here My mistake has lead to greater insight.
|
1

Try this one:

return (from TT in _er.TimeTables
        where TT.Startdate == CoeStartdate
        select new  
        {
            CStartdate = TT.Startdate.Value.ToString() ,
            TimeTableID = TT.TimeTableID 
        }
        ).AsEnumerable()
         .Select(x=> new Class_CourseStartdate
         {
             CStartdate = x.CStartdate.Value.ToString(),
             TimeTableID = x.TimeTableID
         }).ToLIst();

This way you fecth the data from the database and then you apply the formatting you want.

1 Comment

change it back to AsEnumerable quick
0

Most functions that are not in defined in LINQ namespace can not be used inside LINQ expressions for IQueryabe (ToString being one of those). The solution is to just copy the value as it is and perform the conversion afterwards, or replace the LINQ with a for loop to iterate through the values, in which case you can use your ToString correctly.

Comments

0

First of all, you have a possible exception there: TT.StartDate may be null and when calling Value you'll get an exception.

Second of all, why is CStartDate a string? You won't be able to perform DateTime specific operations with it and you may encounter problems when converting a string back to DateTime if the conversion is made on a thread with different culture.

As a quick fix, you can try adding a second projection to your query, after loading data in memory:

return _er.TimeTables
    .Where(tt => tt.Startdate == CoeStartdate)
    .Select(tt => new { StartDate = tt.StartDate, Id = tt.TimeTableID})
    .ToList()
    .Select(tt => new Class_CourseStartDate
    {
        // Avoid the exception by checking if property has value
        CStartDate = tt.StartDate.HasValue ? tt.StartDate.Value.ToString() : String.Empty,
        TimeTableId = tt.Id
    })
    .ToList();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.