2

Sorry for the wall of text please don't TLDR. I have a very simple object model, basically it's

public class Colony
{
    public virtual IList<Ant> Ants { get; set; }
}

public class Ant 
{
    public bool Dead { get; set }
    public virtual IList<Egg> Eggs { get; set; }
}

public class Egg
{
   public bool Dead { get; set }
   public virtual int IncubationPeriod { get; set; }
}

You get the idea. So I have declared two mapping overrides.

public class ColonyMappingOverride : IAutoMappingOverride<Colony>
{
    public void Override(AutoMapping<Colony> mapping)
    {
        mapping.HasMany(c => c.Ants).Where(x => !x.Dead);
    }
}

public class AntMappingOverride : IAutoMappingOverride<Ant>
{
    public void Override(AutoMapping<Ant> mapping)
    {
        mapping.HasMany(c => c.Eggs).Where(x => !x.Dead);
    }
}

So when I grab data out of the DB I end up with inconsistent data.

For example:

Colony.Ants doesn't contain any dead ants (as expected), however Colony.Ants[0].Eggs contains all Eggs... dead or not.

If I call a Session.Refresh(Colony.Ants[0]) the dead eggs get removed.

Anyone know why lazy loading is ignoring the Where clause on the Ants mapping override?

Stewert
  • 101
  • 1
  • 3
  • does result change if you delete overrides? – Mert Jun 30 '15 at 08:24
  • No, the only thing that happens is when I perform the session.refresh it no longer removes the dead eggs. – Stewert Jul 06 '15 at 13:31
  • could you be sure your overrides run by configiration http://stackoverflow.com/questions/6413767/can-auto-mappings-conventions-work-with-mapping-overrides – Mert Jul 07 '15 at 07:42
  • I don't understand what it is your implying, the link you've posted doesn't seem to relate to what it is your saying. The overrides are part of the NHib config because when I call a refresh on the Ant it applies the override and removes dead eggs. I don't expect to have to call a NHIb Session.Refresh on each ant in the list of ants for it to apply the overrides. I would have thought that at the point of lazy loading or when it gets the parent object it would apply the overrides. But it doesn't. – Stewert Jul 08 '15 at 13:17
  • I always try to avoid stuff like `Refresh` (and `Merge` and the other weird methods) and filtered collections and stuff. It just doesn't feel right. – Stefan Steinegger Jul 22 '15 at 06:17

1 Answers1

0

it works for me using FNH 2.0.1.0 and NH 4.0.0.4000 and following fixed code

public class Colony : Entity
{
    public Colony()
    {
        Ants = new List<Ant>();
    }
    public virtual IList<Ant> Ants { get; set; }
}

public class Ant : Entity
{
    public Ant()
    {
        Eggs = new List<Egg>();
    }
    public virtual bool Dead { get; set; }
    public virtual IList<Egg> Eggs { get; set; }
}

public class Egg : Entity
{
    public virtual bool Dead { get; set; }
    public virtual int IncubationPeriod { get; set; }
}

public class ColonyMappingOverride : IAutoMappingOverride<Colony>
{
    public void Override(AutoMapping<Colony> mapping)
    {
        mapping.HasMany(c => c.Ants).Where(x => !x.Dead);
    }
}

public class AntMappingOverride : IAutoMappingOverride<Ant>
{
    public void Override(AutoMapping<Ant> mapping)
    {
        mapping.HasMany(c => c.Eggs).Where(x => !x.Dead);
    }
}

code

var config = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory().ShowSql().FormatSql())
    .Mappings(m => m
        .AutoMappings.Add(AutoMap.AssemblyOf<Ant>()
            .Conventions.Add(DefaultCascade.All())
            .Override<Colony>(new ColonyMappingOverride().Override)
            .Override<Ant>(new AntMappingOverride().Override)
        )
    )
    .BuildConfiguration();

using (var sf = config.BuildSessionFactory())
using (var session = sf.OpenSession())
{
    new SchemaExport(config).Execute(true, true, false, session.Connection, null);

    using (var tx = session.BeginTransaction())
    {
        session.Save(new Colony
        {
            Ants =
            {
                new Ant
                {
                    Dead = true,
                    Eggs = 
                    {
                        new Egg { Dead = true, IncubationPeriod = 1 },
                        new Egg { Dead = false, IncubationPeriod = 2 },
                    }
                },
                new Ant
                {
                    Dead = false,
                    Eggs = 
                    {
                        new Egg { Dead = true, IncubationPeriod = 1 },
                        new Egg { Dead = false, IncubationPeriod = 2 },
                    }
                },
            }
        });

        tx.Commit();
    }
    session.Clear();

    var result = session.QueryOver<Colony>()
        .Fetch(c => c.Ants).Eager
        .SingleOrDefault();

    Console.WriteLine(result.Ants[0].Eggs.All(e => !e.Dead));
}
Firo
  • 30,626
  • 4
  • 55
  • 94