Mapping Composite key nhibernate with Firebird bank

Asked

Viewed 658 times

1

Guys I’m having difficulty in mapping composite primary key using nhibernate Fluent. I have the following class:

 public class NotaItem
{
    public NotaItem(){}

    public virtual int Id { get; set; } //chave primaria
    public virtual Int16 NumeroSequencialItem { get; set; } //chave primaria
    public virtual Int16 NumeroOrdem { get; set; }
}

Mapping:

 public class NotaItemMap : ClassMap<NotaItem>
{
    public NotaItemMap()
    {
        Table("NOTITEM");

        //Chave primária
        CompositeId().KeyReference(x => x.Id, "NOTIT_ID")
       .KeyProperty(x =>  x.NumeroSequencialItem, "NOTIT_NR_SEQUENCIAL_ITEM");

        Map(x => x.NumeroOrdem)
       .Column("NOTIT_NR_ORDEM")
       .Not.Nullable();
    }
}

I would like to know how best to implement this, because it is not working in this way. Note: Primary key fields is not auto increment.

Log of exception: Execution :

Fluentnhibernate.cfg.Fluentconfigurationexception: An invalid or incomplete Configuration was used while Creating a Sessionfactory. Check Potentialreasons Collection, and Innerexception for more Detail.

---> Fluentnhibernate.cfg.Fluentconfigurationexception: An invalid or incomplete Configuration was used while Creating a Sessionfactory. Check Potentialreasons Collection, and Innerexception for more Detail.

---> Nhibernate.Mappingexception: Could not Compile the Mapping Ocument: (Xmldocument) ---> Nhibernate.Mappingexception: Posit-id class must override Equals(): Trainingnhibernate.Core.Entity.Notaitem in Nhibernate.cfg.Xmlhbmbinding.ClassCompositeIdBinder.Checkequalsandgethashcodeoverride() in Nhibernate.cfg.Xmlhbmbinding.ClassCompositeIdBinder.Bindcompositeid(Hbmcompositeid idSchema, Persistentclass rootClass) in Nhibernate.cfg.Xmlhbmbinding.RootClassBinder.Bind(Hbmclass classSchema, Idictionary2 inheritedMetas) em NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddEntitiesMappings(HbmMapping mappingSchema, IDictionary2 inheritedMetas) in Nhibernate.cfg.Xmlhbmbinding.MappingRootBinder.Bind(Hbmmapping mappingSchema) in Nhibernate.cfg.Configuration.Adddeserializedmapping(Hbmmapping mappingDocument, String documentFileName) --- End of tracking stack of internal exceptions --- in Nhibernate.cfg.Configuration.Logandthrow(Exception Exception) in Nhibernate.cfg.Configuration.Adddeserializedmapping(Hbmmapping mappingDocument, String documentFileName) Nhibernate.cfg.Configuration.Processmappingsqueue() in Nhibernate.cfg.Configuration.Addinputstream(Stream xmlInputStream, String name) in Nhibernate.cfg.Configuration.Adddocument(Xmldocument doc, String name) in Nhibernate.cfg.Configuration.Adddocument(Xmldocument doc) in Fluentnhibernate.PersistenceModel.Configure(Configuration cfg) in Fluentnhibernate.cfg.Mappingconfiguration.Apply(Configuration cfg)
in Fluentnhibernate.cfg.Fluentconfiguration.Buildconfiguration()
--- End of stack tracking of internal exceptions --- in Fluentnhibernate.cfg.Fluentconfiguration.Buildconfiguration() in Fluentnhibernate.cfg.Fluentconfiguration.Buildsessionfactory() ---- End of stack tracking of internal exceptions --- in Fluentnhibernate.cfg.Fluentconfiguration.Buildsessionfactory() in TreinamentoNHibernate.Data.SessionFactory.SessionFactoryUtil.. cctor() in E: Visualcsharp Projects Trainingnhibernate Trainingnhibernate.Data Sessionfactory Sessionfactoryutil.Cs:line 46

  • What problem are you with the current implementation?

  • What is going wrong that you expected a different result? Your composite key mapping, as far as I could see, is correct!

  • Can edit the question with error logging at login?

  • The exception is raised when fetching database data.

  • I ran a test implementing with a simple key: Id(t => t.Id). Column("NOTIT_ID"); I changed the whole line of "Compositeid()" by the one above and it worked. No exception!

2 answers

2


The problem is described in the log stack error in the following line: composite-id class must override Equals(), where to use and map a CompositeId (composite key) in your mapping, you should override the Equals() of its entity, causing it to represent the keys composed in a unique way.

In your case something like this:

// override object.Equals
public override bool Equals(object obj)
{
    if (obj == null || GetType() != obj.GetType())
    {
        return false;
    }

    NotaItem other = obj as NotaItem;
    if (other == null)
        return false;
    if (Id == other.Id && NumeroSequencialItem == other.NumeroSequencialItem)
        return true;
    return base.Equals(obj);
}
  • Vlw man, thank you so much. It worked.. That’s just what I needed. I come from java and I’m starting now with C#.

  • @Marcosvinicius, glad you solved it! If you really solved your question you can mark the answer as solved, and as you seem to be new here at a glance therein and therein.

0

For a composite key, the above answer almost meets the problem;

has another solution, so:

Entity

    public class ItemNota
    {
        public virtual int NumeroNota { get; set; }
        public virtual Int32 Serie { get; set; }
        public virtual int Sequencial { get; set; }


        public override bool Equals(object obj)
        {
            var other = obj as ItemNota;

            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;

            return this.NumeroNota == other.NumeroNota && this.Serie == other.Serie && this.Sequencial == other.Sequencial;
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hash = GetType().GetHashCode();
                hash = (hash * 31) ^ this.NumeroNota.GetHashCode();
                hash = (hash * 31) ^ this.Serie.GetHashCode();
                hash = (hash * 31) ^ this.Sequencial.GetHashCode();

                return hash;
            }
        }
    }

Mapping

    public class ItemNotaMap : ClassMap<ItemNota>
    {
        public ItemNotaMap ()
        {
            CompositeId()
               .KeyProperty(c => c.NumeroNota, "oennotnum")
               .KeyProperty(c => c.Serie, "oennotser")
               .KeyProperty(c => c.Sequencial, "oenseq");

         ...     

            Table("itemnota");
        }
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.