简体   繁体   中英

Fluent nHibernate map HasMany to Entity/Table with no Primary Key

I am having the worst trouble trying to setup a HasMany relationship to an entity backed by a table with no primary key.

ClassA has a CompositeId . To circumvent the lack of a primary key on ClassB , I tried to create a CompositeId on ClassB that was comprised all of the columns in the table. No matter what I've tried, nothing has worked.

These are my classes and mappings.

public class ClassA
{
    public virtual int a_1_id {get;set;}
    public virtual string a_2_id {get;set;}

    public virtual IList<classB> ClassBs { get; set; }

    public override int GetHashCode()
    {
        int hashCode = 0;
        hashCode = hashCode ^ a_1_id ^ a_2_id.GetHashCode();
        return hashCode;
    }

    public override bool Equals(object obj)
    {
        var toCompare = obj as ClassB;

        return (toCompare != null) && (this.GetHashCode() != toCompare.GetHashCode());
    }
}

public class ClassAMap : ClassMap<ClassA>
{
    public ClassAMap()
    {
        Schema("dbo");

        Table("ClassA");

        Not.LazyLoad();

        CompositeId()           
            .KeyProperty(x => x.a_1_id, "a_1_id")
            .KeyProperty(x => x.a_2_id, "a_2_id");      

        HasMany(x => x.ClassBs)
            .Table("ClassB")
            .KeyColumn("a_2_id")
            .Not.LazyLoad();
    }
}

public class ClassB
{
    public virtual string a_2_id {get;set;}
    public virtual string b_field1 {get;set;}

    public override int GetHashCode()
    {
        int hashCode = 0;
        hashCode = hashCode         
            ^ a_2_id.GetHashCode() 
            ^ b_field1.GetHashCode();

        return hashCode;
    }

    public override bool Equals(object obj)
    {
        var toCompare = obj as ClassB;

        return (toCompare != null) && (this.GetHashCode() != toCompare.GetHashCode());
    }
}

public class ClassBMap : ClassMap<ClassB>
{
    public ClassBMap()
    {
        Schema("dbo");

        Table("ClassB");

        Not.LazyLoad();

        CompositeId()           
            .KeyProperty(x => x.a_2_id, "a_2_id")
            .KeyProperty(x => x.b_field1, "b_field1");      
    }
}

you do not need to map classB as entity if it is dependet on ClassA.

public class ClassA
{
    public virtual int Id1 {get;set;}
    public virtual string Id2 {get;set;}

    public virtual IList<string> Bs { get; private set; }

    public override int GetHashCode()
    {
        return (Id1 << 16) ^ Id2.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var toCompare = obj as ClassA;

        return (toCompare != null) && (this.Id1 == toCompare.Id1) && (this.Id2 == toCompare.Id2);
    }
}

public class ClassAMap : ClassMap<ClassA>
{
    public ClassAMap()
    {
        Schema("dbo");

        Table("ClassA");

        Not.LazyLoad();

        CompositeId()           
            .KeyProperty(x => x.Id1, "a_1_id")
            .KeyProperty(x => x.Id2, "a_2_id");

        HasMany(x => x.ClassBs)
            .AsSet()
            .Table("ClassB")
            .KeyColumn("a_2_id")
            .Not.LazyLoad(),
            .Element("b_field1");  // if there is only 1 value column or
            .Component(c =>        // if there is more than 1 value column
            {
                c.ParentReference(x => x.A);
                c.Map(x => x.Value1, "b_field1");
                c.Map(x => x.Value2, "b_field2");
                c.Map(x => x.Value3, "b_field3");
            });
    }
}

public class ClassB
{
    public virtual ClassA A {get;set;}
    public virtual string Value1 {get;set;}
    public virtual string Value2 {get;set;}
    public virtual string Value3 {get;set;}
}

Note: the gethashcode implementation of ClassA is plain wrong and Euqals should not rely on hashcode because it will have collisions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM