HasMany上的FNH映射覆盖

时间:2015-06-29 13:17:23

标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping

对不起文字墙请不要TLDR。 我有一个非常简单的对象模型,基本上是

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; }
}

你明白了。所以我已经声明了两个映射覆盖。

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);
    }
}

因此,当我从数据库中获取数据时,我最终会得到不一致的数据。

例如:

Colony.Ants不含任何死蚂蚁(如预期的那样),但Colony.Ants [0] .Eggs包含所有鸡蛋......死了或不死。

如果我打电话给Session.Refresh(Colony.Ants [0]),死蛋就会被删除。

任何人都知道为什么延迟加载忽略了Ants映射覆盖的Where子句?

1 个答案:

答案 0 :(得分:0)

它适用于我使用FNH 2.0.1.0和NH 4.0.0.4000并遵循固定代码

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);
    }
}

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));
}