Breeze js AutoGeneratedKeyType всегда равен «none» с ODataConventionModelBuilder

У меня есть простой объект poco entityframework

public partial class Location: Entity
{
    [Key]
    public int Id { get; set; }
    public string Description { get; set; }
}

Объект baseClass выглядит следующим образом

public abstract class Entity : IObjectState
{
    [NotMapped]
    public ObjectState ObjectState { get; set; }
}

Я выставляю этот объект через службу Odata, используя ODataConventionModelBuilder.

        var server = GlobalConfiguration.DefaultServer;
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.Namespace = "MyNameSpace.Models";
        builder.EntitySet<Location>(typeof(Location).Name);
        var model = builder.GetEdmModel();
        config.Routes.MapODataServiceRoute("odata", "odata", model, new DefaultODataBatchHandler(server));


        config.AddODataQueryFilter();

Когда я использую этот сервис с Breeze js, я получаю сообщение об ошибке от бриза, когда пытаюсь создать объект с помощью manager.CreateEntity().

Невозможно прикрепить объект к EntityManager без предварительной установки его ключа или установки его свойства entityType 'AutoGeneratedKeyType' в значение, отличное от 'None'

Когда я запрашиваю сущность, редактирую данные и сохраняю их. Все в порядке.

Я использую angular в сочетании с ветерком на клиенте и Asp.net webapi 2 в сочетании с odatacontroller на сервере с EntityFramework 6 в качестве ORM.

Может кто подскажет что я делаю не так!!!


person Gabe    schedule 21.08.2014    source источник


Ответы (1)


ODataConventionModelBuilder от Microsoft очень неполный, и они знают об этом (это относится как к OData WebApi v 2.1, так и к v 2.2). Наряду с рядом более мелких проблем, он не поддерживает «ссылочные ограничения» или любую информацию о сгенерированных ключах хранилища. MS знает об этих проблемах, среди прочего, и заявила, что некоторые из них будут исправлены в новой версии где-то в октябре.

А пока у вас есть несколько вариантов.

  • Используйте ODataConventionBuilder, но затем обновите хранилище метаданных Breeze после получения метаданных, чтобы «исправить» отсутствующие или неправильные метаданные.

    myMetadataStore.metadataFetched.subscribe(function(args) {
      var ms = args.metadataStore;
      var entityType = ms.getEntityType("Customer");
      entityType.setProperties({ autoGeneratedKeyType: AutoGeneratedKeyType.Identity });
      dp = entityType.getDataProperty("companyName");
      dp.validators.push(Validator.maxLength({ maxLength: 40 }));
      // etc... 
    });
    
  • Избегайте извлечения метаданных с сервера и просто описывайте метаданные непосредственно в клиенте breeze: (см.: http://www.breezejs.com/documentation/metadata-by-hand)

  • Полностью пропустите OData и используйте реализацию Breeze WebApi (см. http://www.breezejs.com/documentation/aspnet-web-api). Это имеет то преимущество, что является наиболее полной и наиболее надежной реализацией всех функций бриза. Большинство примеров Entity Framework в breeze.js.samples созданы с его помощью.

В общем, мы ДЕЙСТВИТЕЛЬНО рекомендуем последний вариант, если он вам доступен. Прочтите это (http://www.breezejs.com/documentation/odata-server). ) Чтобы получить больше информации.

person Jay Traband    schedule 21.08.2014
comment
Я рассматривал последние варианты, но проблема с последним вариантом заключается в том, что я считаю очень неестественным применять бизнес-логику и шаблоны программирования таким образом. Может быть, вы можете указать мне на пример, где последний вариант используется в сочетании с шаблоном UnitofWork и шаблоном репозитория. - person Gabe; 22.08.2014
comment
Не уверен, что понимаю, API на стороне сервера для обоих могут быть идентичными. ЕДИНСТВЕННАЯ разница может заключаться в основном использовании WebApi. - person Jay Traband; 22.08.2014
comment
Я имею в виду, что я должен использовать одно из событий перед сохранением EFContextProvider вместо сохранения материала, когда я хочу и в том порядке, в котором я хочу. это кажется мне немного неестественным. - person Gabe; 25.08.2014
comment
На самом деле, если вы посмотрите на пример NoDb в репозитории Breeze.js.samples, вы МОЖЕТЕ полностью взять на себя операцию постоянства, если хотите, но это намного больше работы. И... если вы используете EF и сохраняете граф сущностей, то именно EF заказывает ваше сохранение, а не Breeze. - person Jay Traband; 25.08.2014