Pergunta

Eu estou tentando salvar uma entidade mapeada usando NHibernate, mas a minha inserção no banco de dados falha porque a tabela subjacente tem uma coluna que não permite valores nulos e não está mapeada no meu objeto de domínio. A razão não é mapeado é porque a coluna em questão suporta um aplicativo herdado e não tem relevância para a minha candidatura -. Por isso eu gostaria de não poluir a minha entidade com a propriedade legado

Eu sei que eu poderia usar um campo particular dentro da minha classe - mas isso ainda se sente desagradável para mim. Eu tenho ler que eu possa usar um interceptor NHibernate e substituir o método OnSave () para adicionar na nova coluna à direita antes da minha entidade é salvo. Este está provando difícil, pois eu não posso trabalhar para fora como para adicionar uma instância de Nhibernate.type.IType para os tipos de parâmetro de OnSave do meu interceptor.

Meu Entidade aproximadamente parecido com este:

public class Client
{
    public virtual int Id { get; set; }
    public virtual int ParentId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Email { get; set; }
    public virtual string Url { get; set; }
}

E a minha interceptor

 public class ClientInterceptor : EmptyInterceptor
{

    public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
    {
        if (entity is Client)
        {
            /*
              manually add the COM_HOLD column to the Client entity
            */
            List<string> pn_list = propertyNames.ToList();
            pn_list.Add("COM_HOLD");
            propertyNames = pn_list.ToArray();

            List<Object> _state = state.ToList();
            _state.Add(false);
            state = _state.ToArray();

            //somehow add an IType to types param ??

         }
         return base.OnSave(entity, id, state, propertyNames, types);
    }
}

Alguém tem alguma idéia de como fazer isso corretamente?

Foi útil?

Solução

Eu não posso dizer com certeza desde que eu nunca realmente fez isso (como Stefan, eu também preferem simplesmente adicionar uma propriedade privada), mas você pode simplesmente adicionar um NHibernate.Type.BooleanType para a matriz types?

List<IType> typeList = types.ToList();
typeList.Add(new BooleanType());
types = typesList.ToArray();

Editar

Sim, parece que você está certo; os tipos têm um construtor internal. Eu fiz alguma escavação e encontrou TypeFactory:

Os aplicativos devem usar estática métodos e constantes sobre NHibernate.NHibernateUtil se o padrão IType é bom o suficiente. Por exemplo, o TypeFactory só deve ser usado quando a corda precisa ter um comprimento de 300 em vez de 255. Neste ponto, não NHibernate.String não te thecorrect IType. Em vez disso use TypeFactory.GetString (300) e manter um variável local que contém uma referência ao IType.

Portanto, parece que o que você quer é NHibernateUtil:

Fornece acesso a toda a gama de NHibernate tipos built-in. Eu digito casos pode ser usada para os valores de bind Para consultar parâmetros. Também uma fábrica para nova Blobs e Clobs.

typeList.Add(NHibernateUtil.Boolean);

Outras dicas

Pessoalmente eu não iria fazê-lo tão complicado. Gostaria de acrescentar a propriedade privada e atribuir-lhe um valor padrão - terminado. Você também pode considerar um valor padrão no banco de dados, então você não precisa fazer mais nada.

private virtual bool COM_HOLD 
{ 
  get { return false; } 
  set { /* make NH happy */ } 
}

Antes de escrever um interceptor para que eu consideraria escrever um gatilho de banco de dados. Porque com o Interceptor você está "poluindo" a sua camada de acesso a dados. É pode tornar instável e você poderia tem problemas estranhos.

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