1

I am trying to implement an interface from a another project and persist that to a data base using fluent nhibernate. I have figured out how to persist a single instance of the interface but can not figure out how to do the entire list.

My class definitions are as follows:

public interface IRunnable { int Velocity { get; set; } int GetSpeed(); }

public class Person : IRunnable
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    //public virtual IList<Car> Cars { get; set; }

    public Person()
    {
        //this.Cars = new List<Car>();
    }

    public virtual int GetSpeed()
    {
        return -1;
    }

    public virtual int Velocity { get; set; }
}

public class Person1 : IRunnable
{
    public virtual int Id { get; set; }
    public virtual int Age { get; set; }
    public virtual int Velocity { get; set; }

    public virtual int GetSpeed()
    {
        return 0;
    }
}

public class Car
{
    public virtual int Id { get; set; }
    public virtual IRunnable Runnable { get; set; }

    public virtual IList<IRunnable> Runnables { get; set; }

    public Car()
    {
        Runnables = new List<IRunnable>();
    }
}

Mapping definitions are

 public class Person1Map : ClassMap<Person1>
{
    public Person1Map()
    {
        Id(x => x.Id);
        Map(x => x.Age);
        Map(x => x.Velocity);
    }
}

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.Velocity);
        //HasMany(x => x.Cars).Cascade.All();
    }
}

public class CarMap : ClassMap<Car>
{
    public CarMap()
    {
        Id(x => x.Id);

        ReferencesAny<IRunnable>(x => x.Runnable)
            .IdentityType<int>()
            .EntityTypeColumn("RunnableType")
            .EntityIdentifierColumn("RunnableId")
            .AddMetaValue<Person>("P")
            .AddMetaValue<Person1>("P1")
            .Cascade.All();

        HasMany(x => x.Runnables)
            .KeyColumn("RunnableId")
            .Cascade
            .All();

    }
}

The references Any works great for a single instance of the interface how can I use something like this when I have entire list of the interface?

Thanks!

joshwl2003
  • 463
  • 1
  • 7
  • 16

2 Answers2

0

HasMany with interfaces is not that easy, or lets say it has some limitations.

It depends a little bit on your mapping strategy how your inheritance works. Have a look here for documentation.

And you can find a good post already on SO about it here...

Basically you might have to add a class map for your interface and create subclass mappings for your implementations. This would be table per concrete class mapping which should work fine.

Community
  • 1
  • 1
MichaC
  • 13,104
  • 2
  • 44
  • 56
0

The answer for fluent NHibernate is here: https://github.com/jagregory/fluent-nhibernate/issues/56, an extract:

Many-to-any support

We still don't support many-to-any

How the many-to-any is working could be in detailed observed here: Ayende, NHibernate mapping, many-to-any

But the most important information could be found here: 6.10. Heterogeneous Associations

The <many-to-any> and <index-many-to-any> elements provide for true heterogeneous associations. These mapping elements work in the same way as the element - and should also be used rarely, if ever.

NOTE: Please, try to re-think your model. My experience is that the simplification from any but short perspective wins. Other words, If we have a class like Tag, which could be referenced almost anywhere... usually we do not introduce IList<A> A, IList<B> B .. into Tag itself. But we still can find the Tags related to A... with some querying

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Using your note how would you model the car class I have outlined? I am confused by this statement usually we do not introduce IList A, IList B .. into Tag itself. – joshwl2003 Jan 07 '14 at 15:34
  • Firstly, if possible, I would not mapp the `IRunnable` to car... if possible. If I would need the *Car* to be using the `IRunnable` stuff as collections, I would go for mapping it as few lists (ie opposite of my NOTE). I would introduce as many mappings as I have persisted implementors. `IList Persons` as first collection and `IList Person1s` ... In upper layers I can publish some virtual Union of these, but during the querying I would use explicit Objects, rather then ``. Summary, until now I've never used ``. Either no mapping or explicit implementor mapping – Radim Köhler Jan 07 '14 at 15:38