2016-10-19 3 views
1

У меня есть несколько проектов, которые возвращают те же объекты OData через конечную точку API. Теперь я хочу вызвать все проекты и сохранить их в базе данных вызывающих проектов с инфраструктурой сущностей.Сохранение объектов OData из api с идентификатором в базу данных в структуре сущности

Чтобы добавить их в db, ID будет перезаписан, но я хочу сохранить идентификатор, который имеет объект в базе данных проектов. поэтому я могу получить к ним доступ, если это необходимо, и проверить, нет ли данных в моей базе данных. Из-за этого мне нужно добавить еще один столбец MainProjectID и projectID в объект.

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

Я в основном хочу сохранить id как не-ключ. Есть ли способ сделать это без написания совершенно новых классов и их разбора вручную?

Любая помощь была бы принята с благодарностью.

+0

Под «перезаписью» вы имеете в виду, что на БД они обрабатываются как столбцы auto_increment, а исходные значения теряются? Если да, взгляните на это: http://stackoverflow.com/questions/7206273/disabling-identity-auto-incrementing-on-integer-primary-key-using-code-first – infiniteRefactor

+0

Да, но я все еще могу " t использовать исходные значения id как ключевые, поскольку они могут сталкиваться друг с другом от проекта к проекту. Поскольку они не все из одного и того же дБ. И так как в основном все объекты будут помещены в ту же таблицу, идентификатор столкнется. – Wouter

+0

Тогда, поскольку вы пытались наследовать и ссылаться, я думаю, вы не можете изменить класс сущности? – infiniteRefactor

ответ

2

У нас есть несколько альтернатив здесь:

  • В распределенной системе, лучший способ справиться с этими видами ID столкновений является сделать идентификаторы глобально уникальным. Если вы можете изменить способ генерации идентификаторов, это будет мой выбор. Вы можете использовать UUID (или GUID реализации Microsoft), который будет генерировать универсальный уникальный идентификатор. Или, если это кажется излишним, вы можете создать простой механизм, который объединяет ID с projectID. Однако вы должны убедиться, что метод, который вы будете использовать, не приведет к каким-либо коллизиям (никакая другая пара id-projectId не будет сопоставляться с одним и тем же значением).

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

  • Вы можете использовать разные объекты для создания и агрегации приложений. Я не знаю вашего приложения, но это похоже на подход OK, поскольку агрегирующее приложение имеет другое представление об объекте. Агрегирующее приложение заботится о том, какое приложение создало объект, что могло бы привести к тому, что идентификатор исходного приложения был бы правдоподобным. Ваши объекты будут отличаться только тем, что, когда вы получаете объект OData из API, вам нужно скопировать все другие свойства и поместить идентификатор проекта самостоятельно.

  • Вы можете использовать предыдущее решение, но вы можете использовать производный класс, чтобы не повторять свойства объекта. Это лучший вариант дизайна. Однако с помощью этого метода у вас будут проблемы с первичным ключом (как вы заявили, что у вас есть). Рассмотрим этот пример

    public class Base { 
        public int ID { get; set; } 
    
        [Required] 
        [StringLength(50)] 
        [Display(Name = "Name")] 
        public string Name { get; set; } 
    } 
    
    public class Derived : Base { 
        [Key] 
        public int projectId {get; set; } 
    } 
    

    Если вы не поставите [Key] к Derived, то вы будете иметь только ID в качестве первичного ключа. Когда вы ставите [Key] в Derived, вы получите только projectId в качестве первичного ключа.Вам нужно определить составной ключ, и вы можете сделать это путем удаления [Key] аннотации из projectId и используя onModelCreating переопределения DbContext

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
        modelBuilder.Entity<Derived>().HasKey(a => new { a.ID, a.projectId }) 
                .Property(c => c.ID).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None); 
        modelBuilder.Entity<Derived>().Property(c => c.projectId).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None); 
    } 
    
  • Вы можете смешать эти альтернативы. Вы можете удалить первичный ключ в поле ID, а затем вы можете вставить новое Entity, которое будет моделировать отношения 1-M между идентификаторами и идентификаторами проекта.

+0

Это решило мою проблему. Очень хороший ответ с множеством хороших вариантов на выбор, а также решение проблемы дизайна повторяющегося кода. Большое спасибо. – Wouter