moe
moe

Reputation: 35

LINQ to Entities does not recognize the method call within it

I completely understand that this is because LINQ query requires the whole expression to be translated to a server , and therefore I cant call an outside method in it. but as I have looked at other answers there is not relative solution to this. the only approach that I thought about is to loop through all the items in the model and than passing them to the query one by one but even though this approach would not help so I am seeking help in here for anyone to help me to figure out how to call a method or a way of calling a method appendstr that initializes a.PostedDate before checking its actual equivalent value in the giving LINQ Query.

[HttpGet]
public ActionResult SearchResult(int? page, string searchTitle = null, string searchLocation = null, string last24 = "")
{


    ViewBag.searchTitle = searchTitle;
    ViewBag.searchLocation = searchLocation;
    ViewBag.page = page;
    ViewBag.last24 = last24;

    setUpApi(searchTitle, searchLocation);
    var result = new List<AllJobModel>().AsQueryable();
    if (!string.IsNullOrEmpty(ViewBag.searchTitle) || !string.IsNullOrEmpty(ViewBag.searchTitle) || !string.IsNullOrEmpty(ViewBag.last24))
    {
        setUpApi(searchTitle, searchLocation);
        DateTime now = DateTime.Now;

        result = db.AllJobModel.Where(a => a.JobTitle.Contains(searchTitle) && a.locationName.Contains(searchLocation) &&
        appendstr(a.PostedDate).Equals(now.AddHours(-24).ToString("MM-dd-yyyy")));
    }
    else
    {
        result = from app in db.AllJobModel select app;
    }


    return View(result.ToList().ToPagedList(page ?? 1, 5));
}

The second method that gets called in the LINQ Query

public string appendstr(string str)
{
    var x = str.Split(' ');

    return  01 + "-" + x[1] + "-" + x[2];
}

Upvotes: 0

Views: 74

Answers (1)

John Wu
John Wu

Reputation: 52210

I think you already understand that the .NET code you write in the Where clause is actually an expression that is parsed and converted to SQL. So if you have a funky string manipulation method, you can't use it directly.

The brute force option, as you seem to already understand, it to materialize the query first and then run the C# code over the results. You can do this with ToList() or AsEnumerable().

result = db.AllJobModel
    .Where
    (
        a => a.JobTitle.Contains(searchTitle)
          && a.LocationName.Contains(searchLocation)
    )
    .AsEnumerable()
    .Where
    (
        a => appendstr(a.PostedDate).Equals(now.AddHours(-24).ToString("MM-dd-yyyy")))
    );

However in your specific case you can try a trick. You are attempting a date comparison, which SQL is perfectly capable of doing... you just need to convert that funky PostedDate to a SQL DateTime so that you can compare it directly. The gimmick for that is to use SqlFunctions.DateAdd to add null interval (e.g. 0 days). This implicitly converts the string to DateTime, where you can now query on the SQL side:

var targetDate = DateTime.Now.AddHours(-24);
result = db.AllJobModel
    .Where
    (
        a => a.JobTitle.Contains(searchTitle)
          && a.LocationName.Contains(searchLocation)
          && SqlFunctions.DateAdd("DAY", 0, a.PostedDate) == targetDate
    );

Credit goes to this post for the workaround.

Upvotes: 1

Related Questions