Ядро Entity Framework: связь с двумя не первичными ключами - PullRequest
0 голосов
/ 16 апреля 2020

Я работаю над старым проектом, в котором я не могу вносить изменения в базу данных, я создаю новый API, используя. net core 3.

У меня есть две таблицы page и Note, которые имеют PageId и BookId вместе, так что каждая заметка имеет одну страницу с одинаковым BookId и PageId

public class Note
{
   public int Id { get; set; }
   public int BookId { get; set; }
   public int PageId { get; set; }
   public string Text { get; set; }
}

public class Page
{
   [Key]
   public int MainId { get; set; } // this is the primary key
   public int BookId { get; set; }
   public int PageId { get; set; }
   public string Content { get; set; }
}

PageId не является первичным ключом для страницы и имеет повторяющиеся значения. Я хочу получить страницу по идентификатору заметки, я делаю это так:

 [HttpGet("{id}")]
 public async Task<ActionResult> GetPageByNoteId(int noteId)
 {
        var note = await db.Notes.FindAsync(id);
        var page = await db.Pages.Where(x => x.BookId == note.BookId && x.PageId == note.PageId)
                                 .FirstOrDefaultAsync();

        return Ok(new {note,page});
 }

Есть ли способ сделать это с одним попаданием в базу данных?


Обновить :

Первичный ключ для страницы - MainId, но он должен быть PageId и BookId вместе, но я не могу внести изменения в базу данных. Если я могу внести изменения в базу данных, я бы сделал следующее к таблице страниц:

  • удалить столбец MainId

  • Сделать PageId и BookId первичным ключом

тогда я могу сделать это:

      modelBuilder.Entity<Note>(entity =>
       {
                   entity.HasOne(Note => Note.Page)
                         .WithOne(page => page.Note)
                         .HasForeignKey<Note>(note => new { note.PageId, note.BookId});

       });

1 Ответ

0 голосов
/ 16 апреля 2020

Может быть, это то, что вы ищете.

  public class Note
    {
        public int Id { get; set; }
        public int BookId { get; set; }
        public int PageId { get; set; }
        public string Text { get; set; }
        public Page Page { get; set; }
    }

    public class Page
    {
        public int Id { get; set; }
        public int BookId { get; set; }
        public int PageId { get; set; }
        public string Content { get; set; }
        public Note Note { get; set; }
    }

И в вашем классе контекста БД.

  protected override void OnModelCreating(ModelBuilder builder)
            {
                base.OnModelCreating(builder);
...
         builder.Entity<Note>()
            .HasOne(r => r.Page)
            .WithOne(x => x.Note);

Теперь вы можете делать, как показано ниже.

 var page = (await _context.Notes.Include(x => x.Page)
                                          .FirstOrDefaultAsync(x => x.Id == id)).Page;

Это решение для случаев, когда у вас есть отношения один к одному от заметки к странице. если это возможно, вы можете изменить свойство Pages на collection.

...