views:

133

answers:

1

I use DTO's to map between my Business and Entity Framework layer via the Repository Pattern.

A Standard call would look like

public IClassDTO Fetch(Guid id)
{
    var query = from s in _db.Base.OfType<Class>()
        where s.ID == id
        select s;

    return query.First();
}

Now I wish to pass in filtering criteria from the business layer so I tried

public IEnumerable<IClassDTO> FetchAll(ISpecification<IClassDTO> whereclause)
{            
    var query = _db.Base.OfType<Class>()
        .AsExpandable()
        .Where(whereclause.EvalPredicate);      

    return query.ToList().Cast<IClassDTO>(); 
}

The Call from the business layer would be something like

Specification<IClassDTO> school =
    new Specification<IClassDTO>(s => s.School.ID == _schoolGuid);

IEnumerable<IClassDTO> testclasses = _db.FetchAll(school);

The problem I am having is that the .Where clause on the EF query cannot be inferred from the usage. If I use concrete types in the Expression then it works find but I do not want to expose my business layer to EF directly.

A: 

Try making FetchAll into a generic on a class instead, like this:-

public IEnumerable<T> FetchAll<T> (Expression<Func<T,bool>> wherePredicate)
  where T:IClassDTO  //not actually needed
{            
    var query = _db.Base.OfType<T>()
        .AsExpandable()
        .Where(wherePredicate);      

    return query; 
}

pass in school.Evalpredicate instead. FetchAll doesn't appear to need to know about the whole specification, it just needs the predicate, right? If you need to cast it to IClassDTO, do that after you have the results in a List.

Hightechrider