NHibernate: Uma class base, vários mapeamentos

Eu sou relativamente novo no NHibernate, mas tenho usado nos últimos programas e estou apaixonado. Cheguei a uma situação em que preciso agregar dados de 4-5 bancos de dados em um único database. Especificamente, são dados do número de série. Cada database terá seu próprio arquivo de mapeamento, mas no final as entidades compartilham a mesma estrutura básica (class serial).

Eu entendo NHibernate quer um mapeamento por class, e assim meu pensamento inicial era ter uma class serial base e, em seguida, herdá-lo para cada database diferente e criar um arquivo de mapeamento exclusivo (a class herdada teria zero conteúdo). Isso deve funcionar muito bem para pegar todos os dados e preencher os objects. O que eu gostaria de fazer é salvar essas classs herdadas (não sei qual é o termo apropriado) para a tabela de class base usando o mapeamento da class base.

O problema é que não tenho idéia de como forçar o NHIbernate a usar um arquivo de mapeamento específico para um object. A conversão da class herdada para a class base não faz nada quando se usa ‘session.save ()’ (não se trata de mapeamento).

Existe uma maneira de especificar explicitamente qual mapeamento usar? Ou há apenas alguma diretora OOP que estou perdendo para lançar mais especificamente uma class herdada para a class base? Ou essa ideia é apenas ruim?

Todo o material de inheritance que eu poderia encontrar com relação ao NHibernate (Capítulo 8) não parece ser totalmente aplicável a essa function, mas eu posso estar errado (a tabela por class de concreto parece útil, mas eu posso) t envolva a minha cabeça completamente com relação a como o NHibernate descobre o que fazer).

Eu não sei se isso vai ajudar, mas eu não estaria tentando fazer isso, basicamente.

Essencialmente, eu acho que você está possivelmente sofrendo da síndrome do “Golder Hammer”: quando você tem um martelo REALMENTE legal (ou seja, Hibernate (e eu compartilho sua opinião sobre isso; é uma ferramenta MAGNÍFICA)), tudo parece um prego.

Eu geralmente tentaria simplesmente ter uma class de “conversão manual”, ou seja, uma que tivesse construtores que pegassem as classs de hibernação para suas Classes Seriais individuais e que simplesmente copiasse os dados para o seu formato específico; então o Hibernate pode simplesmente serializá-lo para o database (único) usando seu próprio mapeamento.

Efetivamente, a razão pela qual eu acho que essa é uma solução melhor é que o que você está efetivamente tentando fazer é ter serialização assimétrica em sua class; Ou seja, ler de um database em sua class derivada, gravar em outro database em sua class base. Nada muito horrível sobre isso, na verdade, exceto que é fundamentalmente um processo unidirecional; Se você realmente quiser a conversão de um database para outro, simplesmente faça a conversão e termine com isso.

Isso pode ajudar;

Usando o NHibernate com vários bancos de dados

Do artigo;

Introdução

… descrito usando o NHibernate com o ASP.NET; ofereceu diretrizes para se comunicar com um único database. Mas às vezes é necessário se comunicar com vários bancos de dados simultaneamente. Para o NHibernate fazer isso, uma fábrica de session precisa existir para cada database com o qual você estará se comunicando. Mas, como é frequentemente o caso com vários bancos de dados, alguns dos bancos de dados raramente são usados. Portanto, pode ser uma boa ideia não criar fábricas de session até que elas sejam realmente necessárias. Este artigo pega onde o artigo anterior do NHibernate com ASP.NET parou e descreve os detalhes de implementação dessa abordagem de som simples. Embora o artigo anterior tenha enfocado o ASP.NET, a sugestão abaixo é suportada no ASP.NET e no .NET.

A primeira coisa a fazer ao trabalhar com vários bancos de dados é configurar as comunicações apropriadas. Crie um arquivo de configuração separado para cada database, coloque-os em uma pasta de configuração central e, em seguida, faça referência a eles a partir do arquivo web / app.config.

Eu não estou 100% certo de que isso vai fazer o que eu preciso, mas eu encontrei este googling hoje sobre NHibernate e tipos anônimos:

http://infozerk.com/averyblog/refactoring-using-object-constructors-in-hql-with-nhibernate/

A parte interessante (para mim, eu sou novo nisso) é a palavra-chave ‘new’ na cláusula HQL select. Então, o que eu poderia fazer é selecionar o SerialX do DatabaseX usando mappingX e passá-lo para um construtor para SerialY (o serial geral / base). Então, agora eu tenho SerialY gerado a partir de mappingX / databaseX e (espero) eu poderia então session.save e NHibernate usará mappingY / databaseY.

A razão pela qual eu gosto disso é simplesmente não ter duas classs com os mesmos dados persistentes (eu acho!). Não há realmente nenhuma diferença funcional entre isso e retornar uma lista de SerialX, iterando através dele e gerando SerialY e adicionando-o a uma nova lista (a primeira e melhor resposta dada).

Isso não tem o benefício mais geral de fazer casos úteis para os mapeamentos do NHibernate com inheritance, mas acho que ele fará as coisas limitadas que eu quero.

Embora seja verdade que você precisará de um arquivo / class de mapeamento para cada uma dessas tabelas, não há nada que impeça você de fazer com que todas essas classs implementem uma interface comum.

Você pode agregá-los todos juntos em uma única coleção na sua camada de aplicação (Ie List), onde cada uma dessas classs implementa List)

Você provavelmente terá que escrever um pouco de encanamento para acompanhar em qual session armazená-lo (já que você está segmentando vários bancos de dados) se desejar fazer atualizações. Mas o processo para fazer isso vai variar dependendo de como você tem as coisas configuradas.

Eu escrevi um post muito longo com código e tudo para responder a Dan. Acabou, acho que perdi o óbvio.

public class Serial { public string SerialNumber {get; set;} public string ItemNumber {get; set;} public string OrderNumber {get; set;} } 

 Serial serial = sessionX.get(typeof(Serial), someID); sessionY.save(serial); 

O NHibernate deve usar mappingX para get e mappingY para salvar, já que as sessões não estão sendo compartilhadas, e o mapeamento está vinculado à session. Assim, posso ter dois mapeamentos apontando para a mesma class porque, em qualquer session específica, há apenas um único mapeamento para o relacionamento de class.

Pelo menos eu acho que é o caso (não posso testar atm).

Infelizmente este caso específico é realmente chato e não é útil. Em um programa diferente do mesmo domínio, sou derivado da class base para uma parte específica da lógica de negócios. Eu não queria criar um arquivo de mapeamento, pois era apenas para facilitar um pequeno pedaço de código. De qualquer forma, eu não poderia fazê-lo funcionar no NHibernate devido às mesmas razões que a minha primeira pergunta e fiz o método que McWafflestix descreve para contornar (desde que era menor).

Dito isto eu encontrei isso via google:

http://jira.nhibernate.org/browse/NH-662

Essa é exatamente a mesma situação e aparece (possivelmente) abordada no NH 2.1+? Eu ainda não o segui.

(nota: Dan, no meu caso eu estou recebendo de vários bancos de dados, apenas escrevendo para um. Eu ainda estou interessado em sua sugestão sobre a interface porque eu acho que é uma boa idéia para outros casos. Você definiria o mapeamento Se eu tentar salvar uma class que implementa a interface que não tem uma definição de mapeamento, o NHibernate usaria o mapeamento de interface? Ou eu teria que declarar subluxações vazias no mapeamento para cada class que implementa o mapeamento de interface?)