Я пытаюсь абстрагировать автоматически сгенерированный класс ODataController в VS 2013, потому что код выглядит идентичным для разных контроллеров, кроме имени POCO, поэтому я сделал следующее:
public abstract class ODataControllerBase<T,DB> : ODataController
where T : class, IIdentifiable, new()
where DB : DbContext, new()
{
protected DB _DataContext;
public ODataControllerBase() : base()
{
_DataContext = new DB();
}
// only one function shown for brevity
[Queryable]
public SingleResult<T> GetEntity([FromODataUri] int key)
{
return SingleResult.Create(_DataContext.Set<T>().Where(Entity => Entity.Id.Equals(key)));
}
}
IIdentifiable
- это интерфейс, который заставляет параметр T иметь читаемое/записываемое свойство Id integer.
Реализация выглядит так (POCOs и DataContexts должны быть уже созданы)
public class MyObjectsController : ODataControllerBase<MyObject,MyDbContext>
{
public MyObjectsController() : base()
{
}
// That it - done because all the repetitive code has been abstracted.
}
Теперь моя функция регистрации WebApiConfig содержит только следующее:
public static void Register(HttpConfiguration config)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<MyObject>("MyObjects");
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
}
Я запускаю проект http://localhost:10000/odata/MyObjects
, и я получаю ответ:
<m:error>
<m:code/>
<m:message xml:lang="en-US">No HTTP resource was found that
matches the request URI `http://localhost:10000/odata/MyObjects.`
</m:message>
<m:innererror>
<m:message>No routing convention was found to select an action
for the OData path with template '~/entityset'.
</m:message>
<m:type/>
<m:stacktrace/>
</m:innererror>
</m:error>
Что не хватает? Что я должен удалить? Это то, что мы не можем сделать, т.е. Действительно ли нам нужно наследовать ODataController
напрямую без промежуточного родительского класса?