2017-01-18 1 views
0

Je suis coincé d'environ 12 heures avec cette erreur alors pouvait-on me aider au moins à comprendre ce qui est fauxNHibernate Illégalement a tenté d'associer une procuration à deux sessions ouvertes

Voici mon code

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

Voici mon test

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

la chose étrange est que si je remplace cette pièce dans mon code

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

Par cette

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

Si je le remplace l'erreur disparaît si quelqu'un pouvait me aider à comprendre cette erreur.

Edition - Cela pourrait être utile

De Stack Trace je suis que l'exception soit lancée à partir de cette méthode spécifiquement sur la ligne 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); 
    } 
} 
+0

comment exactement créez-vous la session? –

Répondre

0

Listes (IList, ISet ...) et les références des entités sont des proxies dans NHibernate. Cela vous permet de les charger paresseux. L'exception vous indique que vous utilisez l'un de ces proxys dans deux sessions ouvertes. Cela signifie que vous chargez une entité dans une session et essayez de la sauvegarder dans une autre. Si cela est prévu, fermez la première session avant d'utiliser la suivante. Je recommanderais d'utiliser le motif UnitOfWork pour éviter un tel comportement.

+0

Je me suis assuré que différentes fois que la session a la même Id de session est la même en utilisant DataSessionContext.Session – user3260672

+0

Malheureusement NHibernate a une autre opinion ^^ Vous pouvez essayer [NHibernate Profiler] (https://www.hibernatingrhinos.com/products/nhprof) pour vérifier les sessions ouvertes. C'est gratuit pendant 30 jours et imho un outil essentiel pour chaque développeur qui travaille avec NHibernate. – Rabban

+0

merci @Rabban – user3260672