NHibernate Illegally试图将代理与两个打开的Sessions关联起来

时间:2017-01-18 09:18:09

标签: c# nhibernate fluent-nhibernate

我因为这个错误而被困12个小时左右所以任何人都可以帮助我至少理解错误

这是我的代码

public virtual void AssignAssets(IList<long?> assetsIds, ManualAssetAssignment<TAsset>.AssignmentMode mode, IQueryableRepository<TAsset, long?> assetRepository)
{
    this.Assets.Clear();
    if (mode == AssignmentMode.Execlusion)
    {
        //IList<long?> includedAssetsIds = assetRepository.Find().Where(entity => !assetsIds.Contains(entity.Id)).Select(entity => entity.Id).ToList();
        IList<TAsset> includedAssets = assetRepository.Find().Where(entity => !assetsIds.Contains(entity.Id)).ToList();
        foreach (var asset in includedAssets)
        {
            this.Assets.Add(asset);
        }
    }
    else
    {
        foreach (var assetId in assetsIds)
        {
            var asset = assetRepository.Get(assetId);
            this.Assets.Add(asset);
        }
    }
    _areAssetsEvaluated = true;
}

这是我的测试

using (var tx = DataSessionContext.Session.BeginTransaction())
{
    atm = new Atm(AtmTestData.AutoCompleteCommand(new Atm.SetupCommand() { }), commandDependencyRegistry);
    atmRepository.Save(atm);
    List<long?> atmIds = new List<long?> { atm.Id };

    var command = AtmExpenseTestData.AutoCompleteCommand(new AssetExpense<Atm>.SetupCommand());
    expense = new AssetExpense<Atm>
    (
        command, commandDependencyRegistry
    );

    var assignCommand1 = new AssetExpense<Atm>.ManualAssetAssignmentCommand()
    {
        AssetsIds = new List<long?>() { atm.Id.Value },
        Mode = ManualAssetAssignment<Atm>.AssignmentMode.Execlusion
    };
    assignCommand1.Execute(expense, commandDependencyRegistry);
    atmAssetExpenseRepository.Save(expense);

    tx.Commit();
}

奇怪的是,如果我在我的代码中替换这件作品

IList<TAsset> includedAssets = assetRepository.Find().Where(entity => !assetsIds.Contains(entity.Id)).ToList();
foreach (var asset in includedAssets)
{
    this.Assets.Add(asset);
}

通过这个

IList<long?> includedAssetsIds = assetRepository.Find().Where(entity => !assetsIds.Contains(entity.Id)).Select(entity => entity.Id).ToList();
foreach (var assetId in includedAssetsIds)
{
    this.Assets.Add(assetRepository.Get(assetId));
}

如果我更换它,错误消失,所以任何人都可以帮助我理解这个错误。

修改 - 这可能会有所帮助

从Stack Trace我得到了特别是在第13行return (TId)((ISession)Session).Save(entity);

上从这个方法抛出的异常
public virtual TId Save(TAggregateRoot entity, Action commitPostAction, Action rollbackPostAction, bool propagatePostActionError = false)
{
    if (entity == null)
    {
        throw new ArgumentNullException("entity");
    }

    if (entity is IValidatable)
    {
        ((IValidatable)entity).Validate();
    }
    RegisterPostActions(commitPostAction, rollbackPostAction, propagatePostActionError);
    if (Session is ISession)
    {
        return (TId)((ISession)Session).Save(entity);
    }
    else
    {
        return (TId)((IStatelessSession)Session).Insert(entity);
    }
}

1 个答案:

答案 0 :(得分:0)

列表(IListISet ...)和实体的引用是NHibernate中的代理。这允许您延迟加载它们。该异常告诉您在两个打开的会话中使用此代理之一。这意味着您在一个会话中加载实体并尝试将其保存在另一个会话中。如果是这样,请在使用下一个会话之前关闭第一个会话。我建议使用UnitOfWork Pattern来防止这种行为。