problem with NHibernate one-to-many relationship Collection with cascade

风格不统一 提交于 2019-12-02 08:20:26
Assert.IsTrue(ag.Assets.Contains(a1));  // failed

This could would indeed fail. You have to manage the bi-directional relationship. By this I mean,

In AssetGroup:

virtual public bool AddAsset(Asset asset)
{
    if (asset != null && _assets.Add(asset))
    {
        asset.AssetGroup = this;
        return true;
    }
    return false;
}

... and a corresponding remove

In Asset:

virtual public bool SetAssetGroup(AssetGroup group)
{
    this.AssetGroup = group;
    group.Assets.Add(this);
}

Note the difference between your code and the one above. This is not the only way of doing it, but it's the most mapping-agnostic, safe way of doing it... so whether you set inverse=true on your mapping or not, it'll work. I do it by default without even thinking about it too much.

When working with the model from the outside, you use AddXXX, RemoveXXX, SetXXX. When working with the model from the inside you reference the properties and collections directly. Adopt this as a convention, and you'll be ok for most of the common bi-directional mapping scenarios.

Having said this, I'm not sure why this code fails:

Assert.IsTrue(ag2.Assets.Contains(aa1));

ag2 is from a new query, so that should be ok ... unless the session cached the object, which I don't think it does... but I'm not sure.

I added session.Refresh(ag) and then it works . Is session Refresh an expensive operation ? Is there any alternative

[TestMethod]
public void Can_Use_ISession()
{
    ISession session = TestConfig.SessionFactory.GetCurrentSession();
    var ag = new AssetGroup { Name = "NHSession" };
    session.Save(ag);

    var a1 = new Asset { Name = "s1" };
    var a2 = new Asset { Name = "s2" };

    a1.SetAssetGroup(ag);
    a2.SetAssetGroup(ag);

    session.Flush();
    session.Refresh(ag);

    Assert.IsTrue(a1.Id != default(Guid)); // ok
    Assert.IsTrue(a2.Id != default(Guid)); // ok

    var enumerator = ag.Assets.GetEnumerator();
    enumerator.MoveNext();
    Assert.IsTrue(ag.Assets.Contains(enumerator.Current));  // failed

    Assert.IsTrue(ag.Assets.Contains(a1));  // failed
    Assert.IsTrue(ag.Assets.Contains(a2));  // failed 

    var agRepo2 = new NHibernateRepository<AssetGroup>(TestConfig.SessionFactory, new QueryFactory(TestConfig.Locator));
    Assert.IsTrue(agRepo2.Contains(ag)); // ok
    var ag2 = agRepo2.FirstOrDefault(x => x.Id == ag.Id);
    Assert.IsTrue(ag2.Assets.FirstOrDefault(x => x.Id == a1.Id) != null); // ok
    Assert.IsTrue(ag2.Assets.FirstOrDefault(x => x.Id == a2.Id) != null); // ok

    var aa1 = session.Get<Asset>(a1.Id);
    var aa2 = session.Get<Asset>(a2.Id);
    Assert.IsTrue(ag2.Assets.Contains(aa1));  // failed
    Assert.IsTrue(ag2.Assets.Contains(aa2));  // failed

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!