Suppose I have the following (for showing an item in a drop-down list):
class SelectItemViewModel<TId>
{
string Name {get; set;}
TId Id {get; set;}
}
as well as this on my database entities:
interface IEntity<TId>
{
TId Id {get;
}
I would like to be able to reuse logic to create these drop-down items, passing in something for the name. For example, right now I have (simplified):
List<SelectItemViewModel<int>> GetAvailableEntity1Items(IQuerable<Entity1> entities)
{
return entities
.Select(e => new SelectItemViewModel<int>
{
Id = e.Id,
Name = e.Title
})
.ToList();
}
List<SelectItemViewModel<short>> GetAvailableEntity2Items(IQuerable<Entity2> entities)
{
return entities
.Select(e => new SelectItemViewModel<short>
{
Id = e.Id,
Name = e.Description
})
.ToList();
}
They obviously have the same basic structure. I would like to just operate on IEntity<T> and pass in the "get name" function, but I can't get it to work with Entity Framework.
Doesn't work:
List<SelectItemViewModel<TId> GetAvailableItems<TEntity, TId>(IQueryable<TEntity> entitiesQuery, Func<TEntity, string> getNameForEntity)
where TEntity : class, IEntity<TId>
{
return entitiesQuery
.Select(e => new SelectItemViewModel<TId>
{
Id = e.Id,
Name = getNameForEntity(e)
}
}
and I can't figure out how I'd implement
List<SelectItemViewModel<TId> GetAvailableItems<TEntity, TId>(IQueryable<TEntity> entitiesQuery, Expression<Func<TEntity, string>> getNameForEntity)
where TEntity : class, IEntity<TId>
{
return entitiesQuery
.Select(e => new SelectItemViewModel<TId>
{
Id = e.Id,
Name = ??
}
}
Is there any way to reuse logic here? The only other thing I can think is another interface e.g. IHasName to get the name, but frankly I don't want the database entities responsible for indicating how they should be displayed in the UI layer.