Reputation: 10100
I am using Entity Framework to access my domain models, all of which implement an interface (IPublishable) that specifies properties to indicate whether an item has been published.
When accessing items from the front end I always want to filter out unpublished items. So, every time I write a query I'm doing something similar to this (where the following DbSets Objects1 and Objects2 both implement IPublishable
context.Objects1.Where( x => x.IsPublished ...).OrderBy( x => x.Id).ToList()
context.Objects2.Where( x => x.IsPublished ...).First()
What would be ideal is if I could inject the common Where()
clause into all my queries within my web app OR if there was a way to write an extension method which I could include in each query.
I tried to create the extension method for all linq queries
public static IEnumerable<T> FrontEnd<T>(this DbSet<T> dbSet) where T : class {
return dbSet.Cast<IPublishable>().Where( x => x.IsPublished ...).Cast<T>();
}
And use like this...
context.Objects1.FrontEnd().Where( x => ...).OrderBy(...
However I get the error "LINQ to Entities only supports casting EDM primitive or enumeration types"
I'm new to EF, so any information would be a great help. Thanks
Upvotes: 3
Views: 3056
Reputation: 14580
UPDATED as per comments - this works
public static IQueryable<T> FrontEnd<T>(this DbSet<T> dbSet)
where T : class, IPublishable
{
return dbSet.Where(x => x.IsPublished);
}
and can be used like this:
context.Objects1.FrontEnd().Where( x => ...).OrderBy(...
You can try either of these options:
public static IQueryable<dynamic> FrontEnd(this DbSet<dynamic> dbSet)
{
return dbSet.Where(x => (x as IPublishable).IsPublished);
}
or
public static IQueryable<T> FrontEnd<T>(this DbSet<T> dbSet)
where T : class, IPublishable
{
return dbSet.Where(x => x.IsPublished);
}
note:
the first option uses dynamic so is slower with the second option you have to specify the type in the call to FrontEnd() e.g.
context.Objects1.FrontEnd<Objects1>().Where( x => ...).OrderBy(...
Upvotes: 2
Reputation: 3531
I think LINQ to Entities does not know how to match the cast operator to SQL request. As a suggestion, you could try something like that:
IEnumerable<IPublishable> ReadPublishable(Expression<Func<DomainModelType, bool>> condition)
The expression act as a predicate. So you pass to the ReadPublishable function a predicate that filters the IPublishable objects you need. I tried successfully but only on simple predicates so, I do not know whether that works if you make use of "is" or "as" operators.
Upvotes: 0