I have the following generic extension method:
public static T GetById<T>(this IQueryable<T> collection, Guid id)
where T : IEntity
{
Expression<Func<T, bool>> predicate = e => e.Id == id;
T entity;
// Allow reporting more descriptive error messages.
try
{
entity = collection.SingleOrDefault(predicate);
}
catch (Exception ex)
{
throw new InvalidOperationException(string.Format(
"There was an error retrieving an {0} with id {1}. {2}",
typeof(T).Name, id, ex.Message), ex);
}
if (entity == null)
{
throw new KeyNotFoundException(string.Format(
"{0} with id {1} was not found.",
typeof(T).Name, id));
}
return entity;
}
Unfortunately Entity Framework doesn't know how to handle the predicate
since C# converted the predicate to the following:
e => ((IEntity)e).Id == id
Entity Framework throws the following exception:
Unable to cast the type 'IEntity' to type 'SomeEntity'. LINQ to Entities only supports casting EDM primitive or enumeration types.
How can we make Entity Framework work with our IEntity
interface?
I was able to resolve this by adding the class
generic type constraint to the extension method. I'm not sure why it works, though.
public static T GetById<T>(this IQueryable<T> collection, Guid id)
where T : class, IEntity
{
//...
}