How do I use Fluent NHibernate ReferencesAny mapping?
Asked Answered
C

1

1

I've read a lot about Fluent NHibernate's ReferencesAny but I haven't seen a complete example. I think I understand most of it, but there is one part I don't get. In the class mapping ReferencesAny(x => x.MemberName) is used to define the relationship to the one or more referenced classes. What is MemberName? How is it defined and how is it used to create the data in the database.

I have three tables, the records in one table can reference records in one of the other two tables. The first two are auto mapped, so the Id field is not specifically defined.

public class Household
{
    public virtual string Name { get; set; }

    public virtual IList<AddressXref> AddressXrefs { get; set; }
}

public class Client
{
    public virtual string Name { get; set; }

    public virtual IList<AddressXref> AddressXrefs { get; set; }
}

I'm not sure if the AddressXref table can be auto mapped. If so I need to find out how to do that too. For now I'll do it the conventional way with Fluent.

public class AddressXref
{
    public virtual int id { get; set; }
    public virtual string TableName { get; set; }
    public virtual Int32 Table_id { get; set; }
    public virtual string Street { get; set; }
    public virtual string City { get; set; }
}

class AddressXrefMap : ClassMap<AddressXref>
{
    public AddressXrefMap()
    {
        Table("AddressXref");
        Id(x => x.id);
        Map(x => x.TableName);
        Map(x => x.Table_id);
        Map(x => x.Street);
        Map(x => x.City);

        ReferencesAny(x => x.TableRef)
            .AddMetaValue<Household>(typeof(Household).Name)
            .AddMetaValue<Client>(typeof(Client).Name)
            .EntityTypeColumn("TableName")
            .EntityIdentifierColumn("Table_id")
            .IdentityType<int>();
    }
}

The part I need help with is how is the TableRef, referred to in ReferencesAny(), member of AddressXref defined in the class?

Also, how it is used in the code when creating data records? I image it will be similar to this:

Household Household = new Household();
Household.Name      = "Household #1";

AddressXref AddrXref = new AddressXref();
AddrXref.Street1   = "123 Popular Street";
AddrXref.City      = "MyTown";
AddrXref.TableRef  = Household;

Session.SaveOrUpdate(AddrXref);    

I love using Fluent with NHibernate, but I'm still amazed at the learning curve. :)

Thanks, Russ

Confocal answered 11/8, 2012 at 6:15 Comment(0)
C
3

since both Household and Client don't share a base class other than object you have to declare it as this:

public class AddressXref
{
    public virtual int Id { get; set; }
    public virtual object TableRef { get; set; }
    public virtual string Street { get; set; }
    public virtual string City { get; set; }
}

and test it like this

if (addrXref.TableRef is HouseHold)
    // it's a household
Cutcliffe answered 13/8, 2012 at 15:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.