Fluent NHibernate - Key Mapping Compound

2

Greetings,

I'm having a hard time and I can not solve it.

I have an application where I created the mapping and everything was working perfectly, but now I need to change it and that's where the problem comes up:

I used NHibernate Fluent for ORM.

I need to create the mapping using a composite key, that is, in SQL language it would look something like this:

select
    *
from
    t1
inner join
    t2
        on  t1.codigo = t2.codigo
        and t1.versao = t2.versao;

And I can not map the "and" of the join.

My mapping looks like this:

public class T1Map : ClassMap<T1>{
    public T2Map() {
        Table("TB_WF_T1");
        Id(x => x.Codigo, "CD_T1").GeneratedBy.Sequence("SEQ_TB_WF_T1");
        Map(x => x.Versao, "CD_VERSAO");
        HasMany(x => x.T2).KeyColumn("FK_CODIGO_T1").LazyLoad().Inverse().Cascade.SaveUpdate();
    }        
}

public class T2Map : ClassMap<T2>{
    public T2Map() {
        Table("TB_WF_T2");
        Id(x => x.Codigo, "CD_T2").GeneratedBy.Sequence("SEQ_TB_WF_T2");
        Map(x => x.Versao, "CD_VERSAO");
        References(x => x.T1).Column("FK_CODIGO_T1").LazyLoad().Cascade.None();
    }
}

My question is how do I map both the "CODE" field and the "VERSION" field.

Is there any way to do this mapping?

Any tips that anyone can help me, I will be very grateful.

    
asked by anonymous 05.02.2016 / 20:32

1 answer

3

I use FluentNHibernate's CompositeId (), and I use the reference. HasMany is if it is any collection I want to bear together. For your code you should already know the difference.

CompositeId()
            .KeyReference(x => x.Id, "idB")//se for uma referencia(entidade)
            .KeyProperty(x => x.Id2, "idB2");//se for uma propriedade(int/long)

Here is an example if it is a class with KeyProperty and KeyReference : ( This Link )

    public class TestChildMap : ClassMap<TestChild>
    {
        public TestChildMap()
        {
            Table("TestChild");
            CompositeId()
                .KeyProperty(x => x.ChildName, "ChildName")
                .KeyReference(x => x.Parent, "TestParentId");
    Map(x => x.Age);
            References(x => x.Parent, "TestParentId")
     .Not.Insert();  //  will avoid "Index was out of range" error on insert
    }

Here is an example if it is a class with only KeyReference :

public class MapEmpresaProduto : MapBase<EmpresaProduto>
    {
        public MapEmpresaProduto()
        {
            Table("EmpresaProduto");
            CompositeId()
                .KeyReference(x => x.Empresa, "IdEmpresa")
                .KeyReference(x => x.Produto, "IdProduto");

            References(x => x.Empresa)
                .Not.Nullable()
                .Fetch.Join()
                .Cascade.SaveUpdate()
                .Column("IdEmpresa")//linko o KeyReference(x => x.Empresa, "IdEmpresa") atraves do column name.
                .ReadOnly();

            References(x => x.Produto)
                .Not.Nullable(

)
                .Fetch.Join()
                .Cascade.SaveUpdate()
                .Column("IdProduto")
                .ReadOnly();
        }
    }

My entity CompanyProduct :

public class EmpresaProduto : EntidadeAuditavelSemId
    {
        public virtual Produto Produto { get; set; }

        public virtual Empresa Empresa { get; set; }

        protected EmpresaProduto()
        {
        }
        public EmpresaProduto(Empresa empresa, Produto produto) : this()
        {
            Produto = produto;
            Empresa = empresa;
        }

        public override bool Equals(object entity)
        {
            if (entity == null || !(entity is EmpresaProduto))
            {
                return false;
            }

            // Mesmas instâncias devem ser consideradas iguais
            if (ReferenceEquals(this, entity))
            {
                return true;
            }

            // Objetos transientes não são considerados iguais
            var other = (EmpresaProduto)entity;
            var typeOfThis = GetType();
            var typeOfOther = other.GetType();
            if (!typeOfThis.IsAssignableFrom(typeOfOther) && !typeOfOther.IsAssignableFrom(typeOfThis))
            {
                return false;
            }

            return Produto.Id.Equals(other.Produto.Id) && Empresa.Id.Equals(other.Empresa.Id);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                var hash = GetType().GetHashCode();
                hash = (hash * 31) ^ Produto.GetHashCode();
                hash = (hash * 31) ^ Empresa.GetHashCode();

                return hash;
            }
        }
    }

OBS: I've done lots of tests and SQLServer so far excelled, being index created with strange and wrong names in MYSQL and postgress. So if your bank is not sqlserver be careful. (The problem is actually in the connector and not in the fluent itself).

    
08.02.2016 / 03:06