0

I'm trying to do a Query in Entity Framework using Repository pattern like this:

Namespace: Services

List<Data.Item> itemToday = repositoryUser.Get(i => i.UserId.Equals(user.Id) &&
                                               i.Created.Date < DateTime.Now.Date)
                                          .ToList();

Namespace: Data (my repository)

public IEnumerable<T> Get(System.Linq.Expressions.Expression<Func<T, bool>> expressionFilter)
{
    return this.dbContext.Set<T>().Where(expressionFilter);
}

This will throw this error:

The specified type member 'Date' is not supported in LINQ to Entities

I found these questions to solve this with an Entity Framework method to convert date types and compare

  1. Compare Date values in Entity Framework
  2. Compare Dates using LINQ to Entities (Entity Framework)

But these solutions use a EF method that's stored in Data namespace, and I'm querying at Service namespace and I shouldn't call a repository function in Service layer, right? So how can I do this?

Community
  • 1
  • 1
  • the `Linq-to-Entities` does not support most of the dot net functions. Look at [this](http://stackoverflow.com/questions/14601676/the-specified-type-member-date-is-not-supported-in-linq-to-entities-only-init) – Manish Mishra Feb 18 '14 at 15:38
  • "I shouldn't call a repository function in Service layer" -> isn't this exactly what you're currently doing with "repositoryUser.Get"? – ken2k Feb 18 '14 at 15:42
  • `i.Created < DateTime.Today` will be sufficient I guess. – Mat J Feb 18 '14 at 15:47
  • @ken2k Yes, but I don't have Entity Framework reference in my Service layer, so I can't call a Entity Framework method. Service layer just have Data (Repository) reference so I can call repositoryUser.Get() that's public, but I can't call a reference's library (like EF). – Kevin Gerrard Feb 18 '14 at 15:58

1 Answers1

0

Since you pass the where down to EF your will need to do it the EF way (look below). Otherwise you will have to parse the query itself and send the correct one onwards to EF, and that is not very easy. I would probably write a method with the parameters needed for the specific scenario:

public List<Data.Item> Get<T>(int id, DateTime createdBeforeDate)
{
     return this.dbContext.Set<T>().Where(i => i.UserId.Equals(id) &&
                                               SqlFunctions.DateDiff("DAY", i.Created, createdBeforeDate) > 0))
                                   .ToList();
}

You can use the SqlFunctions class for these kinds of scenarios. You can use the SqlFunctions.DateDiff function with a parameter of "DAY" (I found the answer here: https://stackoverflow.com/a/14778874/455904).

In your case I believe SqlFunctions.DateDiff("DAY", i.Created, DateTime.Now) > 0) should work

List<Data.Item> itemToday = repositoryUser.Get(i => i.UserId.Equals(user.Id) &&
                                               SqlFunctions.DateDiff("DAY", i.Created, DateTime.Now) > 0))
                                          .ToList();

As a side note DateTime.Today can be used instead of DateTime.Now.Date

Community
  • 1
  • 1
Fredrik Ljung
  • 1,445
  • 13
  • 28
  • 1
    Would suggest something along these lines, but consider looking at the `EntityFunctions.TruncateTime` if you want to keep it a tiny bit tighter to EF – Thewads Feb 18 '14 at 18:38