Есть ли какие-либо примеры AngularJS + ASP.NET-WebApi + OData + Breeze.js + Typescript или кто-то пытался объединить их?

Я пытаюсь объединить эти технологии, но ничего хорошего не получается, так как метаданные структуры сущностей не используются breeze.js, даже во всех конфигурациях, где настройка, это немного сложная ситуация, примеров в буквальном смысле нет, поэтому это мой пример кода, который не работает должным образом, но, возможно, кто-то найдет мою ошибку и в конечном итоге поможет решить эту загадку или найдет ее в качестве отправной точки.

OdataService.ts

'use strict';
module twine.components {
  class MetadataStoreOptions implements breeze.MetadataStoreOptions{
    namingConvention:breeze.NamingConvention = breeze.NamingConvention.defaultInstance;
  }
  class Manager implements breeze.EntityManagerOptions {
    metadataStore: breeze.MetadataStore;
    constructor( public dataService: breeze.DataService) {
    }
  }
  class DataServiceOptions implements breeze.DataServiceOptions {
    serviceName = 'http://twine.azurewebsites.net/odata';
    hasServerMetadata = true;
  }
  export class ODataService {
    options: Manager;
    manager: breeze.EntityManager;
    metadataStore: breeze.MetadataStore;
    storeOptions: MetadataStoreOptions;
    static $inject: string[] = ['$http', '$rootScope'];
    cache: twine.Model.IEntity[];

    constructor(private $http: ng.IHttpService, private $rootScope: ng.IRootScopeService){
      this.storeOptions = new MetadataStoreOptions();
      this.metadataStore = new breeze.MetadataStore(this.storeOptions);
      this.options = new Manager( new breeze.DataService( new DataServiceOptions() ));
      this.options.metadataStore = this.metadataStore;
      this.manager = new breeze.EntityManager( this.options );
      breeze.config.initializeAdapterInstance('dataService', 'webApiOData', true);
      //this.manager.fetchMetadata((meta) => {
      //  this.metadataStore.importMetadata(meta);
      //});
    }

    All( query:breeze.EntityQuery,  successCallback: Function, failCallback?: Function ): void {
      this.manager.executeQuery( query )
        .then( ( data: breeze.QueryResult ) => {
          successCallback( data );
          this.$rootScope.$apply();
        })
        .catch( ( reason: any ) => {
          if ( failCallback ) {
            failCallback( reason );
          }
        });
    }
    Get( key:number,  successCallback: Function, failCallback?: Function ): void {
      //this.manager.fetchMetadata();
      //var entityType = this.manager.metadataStore.getEntityType('Tag');
      //var entityKey = new breeze.EntityKey(entityType, key);
      this.manager.fetchEntityByKey( 'Tag', key )
        .then( ( data: breeze.EntityByKeyResult ) => {
          successCallback( data );
          this.$rootScope.$apply();
        })
        .catch( ( reason: any ) => {
          if ( failCallback ) {
            failCallback( reason );
          }
        });
    }
  }
}

И это tagController.ts

'use strict';
module twine.routes {
  interface ITagsScope extends ng.IScope {
    vm: TagsCtrl;
  }
  interface ITagsCtrl extends twine.components.ITwineRoute{
    tags:any[];
    getTags: () => void;
    tag: any[];
    getTag: (id:number) => void;
  }
  export class TagsCtrl implements ITagsCtrl{
    /* @ngInject */
    static controllerId: string = 'TagsController';
    static controllerAsId: string = 'tagsCtrl';
    static $inject: string[] = ["$scope", "ODataService", '$route'];
    entityQueryName: string = 'Tag';
    query: breeze.EntityQuery;
    tags:any;
    tag: any;
    constructor (private $scope: ITagsScope, private ODataService: twine.components.ODataService, $route: ng.route.IRouteService) {
      this.query = new breeze.EntityQuery(this.entityQueryName);
      if($route.current && $route.current.params.id){
        this.getTag($route.current.params.id);
      }
      else {
        this.getTags();
      }
    }
    getTags() {
      this.ODataService.All(this.query , (data) => {
        this.tags = data.results[0].value;
      }, (error) => {
        console.log('error', error);
      });
    }
    getTag(id:number){
      this.ODataService.Get(id , (data) => {
        this.tag = data.results[0].value;
      }, (error) => {
        console.log('error', error);
      });
    }
  }
}

Есть много ошибок, на разных конфигурациях, иногда этоThere is no resourceName for this query или жеEntityKey must be set, или жеOther stupid errors которые действительно не должны появляться, потому что это машинописный текст, который не допускает несоответствия типов, но сама конфигурация неверна.

И это абстрактный контроллер

[EnableCors(origins: "*", headers: "*", methods: "*")]
public abstract class EntityController<T> : ODataController where T: Entity
{
    protected ODataRepository<T> repo = new ODataRepository<T>();
    private static ODataValidationSettings _validationSettings = new ODataValidationSettings();
    public EntityController()
    {

    }
    // GET: odata/Entity
    [EnableQuery]
    public IQueryable<T> Get(ODataQueryOptions<T> queryOptions)
    {
        try
        {
            queryOptions.Validate(_validationSettings);
        }
        catch (ODataException ex)
        {
            Trace.WriteLine(ex.Message);
            return null;
        }
        return repo.All();
    }

    // GET: odata/Entity(5)
    [EnableQuery]
    public SingleResult<T> Get([FromODataUri] long key, ODataQueryOptions<T> queryOptions)
    {
        try
        {
            queryOptions.Validate(_validationSettings);
        }
        catch (ODataException ex)
        {
            Trace.WriteLine(ex.Message);
            return null;
        }
        return SingleResult.Create(repo.All().Where(x=>x._id == key));
    }
    //ommitted
}

И, наконец, это конфигурация ASP.NET webApi.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Конфигурация и службы веб-API
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        // Маршруты веб-API
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        //CORS
        var cors = new EnableCorsAttribute(
            "*",
            "*",
            "*",
            "DataServiceVersion, MaxDataServiceVersion"
        );
        config.EnableCors(cors);

        // Маршруты Odata
        //config.EnableQuerySupport();
        config.AddODataQueryFilter();

        Builder<Account>(config);
        Builder<Branch>(config);
        Builder<Bucket>(config);
        Builder<Ingredient>(config);
        Builder<Like>(config);
        Builder<Meetup>(config);
        Builder<Shot>(config);
        Builder<Skill>(config);
        Builder<Tag>(config);
        Builder<Team>(config);
    }
    private static void Builder<T>(HttpConfiguration config) where T: class
    {
        var entityType = Activator.CreateInstance<T>().GetType();
        if (entityType != null)
        {
            var builder = new ODataConventionModelBuilder();
            builder.EntitySet<T>(entityType.Name);
            config.Routes.MapODataServiceRoute("odata_" + entityType.Name, "odata", builder.GetEdmModel());
        }

    }
}

Для целей тестирования у меня есть эта рабочая служба OData наhttp://twine.azurewebsites.net/odata/Tag, (в настоящее время CORS не имеет ограничений, не стесняйтесь) последнюю сущность можно изменить на другое имя в зависимости от конфигурации webApiBuild метод. Пожалуйста, не стесняйтесь спрашивать любую другую информацию. Если кому-то нужен весь источник, я готов опубликовать его на github.

Обновить

Забудьте об особом, проблема в методеGet ODataService. Я не могу связать метаданные с сервера на ветер, метод Все работает отлично. Но запросfetchByEntityKey выдает ошибки как описано выше

Ответы на вопрос(3)

Ваш ответ на вопрос