Pergunta

Eu tive uma estrutura seguinte:

User has many books in his history

que foi traduzido para o seguinte

class User { ICollection<Book> History }       // C#
User -> UserHistory (UserId, BookId) -> Book   // DB

Agora quero adicionar uma data à história, criando a seguinte estrutura de classe:

class User { ICollection<Read> History }
class Read { Book Book, Date At }

e mantendo o esquema de DB quase inalterado

User -> UserHistory (UserId, BookId, At) -> Book

Eu quero mapear Read para UserHistory, as perguntas são:

  1. O que devo usar como id no mapeamento de Read? UserHistory A chave primária é (UserId, BookId). Eu preciso de um id Para o NH funcionar?
  2. UserHistory -> Book parece ser um caso de one-to-one. Como especificar o BookId Nome da coluna em UserHistory nesse caso? Eu não vejo um atributo de coluna em one-to-one (E há uma razão para eu ser explícito sobre o nome da coluna).
Foi útil?

Solução

No seu primeiro cenário, o UserHistory era simplesmente uma tabela de mapeamento para um relacionamento de muitos para muitos e não tinha um objeto adequado. Agora, a tabela do usuário/classe de leitura é uma entidade separada, para que precise de um identificador de algum tipo. A maneira mais fácil é adicionar uma chave primária ReadID (ou UserHistoryId) à tabela de história do usuário.

Você não precisa adicionar uma chave separada e pode usar uma chave composta no UserID e no BookID - mas um usuário pode ler um livro mais de uma vez? Supondo que sim, você também precisaria adicionar a coluna AT à tecla composta para torná -la única. Isso fica feio e levará a outros problemas ao lidar com coleções, por isso não vale a pena.

A história do usuário para reservar um relacionamento é realmente um para um e não um para um. Muitos usuários diferentes podem ler o mesmo livro (e talvez o mesmo usuário possa ler um livro mais de uma vez). Pense em muitos para um como referência de objeto.

Outras dicas

Pergunta 1: Não, você não precisa de um ID, apenas pode mapeá-lo como componente (ou elemento composto neste caso, onde está em uma lista)

Pergunta 2: História do usuário-> O livro não é individual, muitos usuários poderiam ter lido o mesmo livro ao longo do tempo, por isso é muitos para um e deve ser mapeado.

Provavelmente o mapeamento incompleto parece seguinte:

<class name="User">

  <bag name="History" table="UserHistory">
    <key name="UserId">
    <composite-element class="Read">
      <property name="At" />
      <many-to-one name="Book" column="BookId" />
    </composite-element>
  </bag>

Nota: Esqueça sobre one-to-one mapeamentos. Isso é usado muito, muito raramente, quando você tem duas tabelas que compartilham a mesma chave primária e são assim vinculadas, na verdade. Na maioria dos casos, você precisa many-to-one, mesmo que no mundo real seja realmente individual.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top