2017-01-18 14 views
0

Я застрял примерно от 12 часов с этой ошибкой, так может ли один помочь мне, по крайней мере, чтобы понять, что это неправильноNHibernate Незаконно пытались связать прокси-сервер с двумя открытыми Sessions

Вот мой код

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

Если я заменю его ошибка исчезнет, ​​так может кто-нибудь помочь мне понять эту ошибку.

Edit - Это может быть полезно

Из стека трассировки я получаю, что исключение будет выброшен из этого метода именно на линии 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

как именно вы создаете сеанс? –

ответ

0

Списки (IList, ISet ...) и ссылки на сущности - это прокси-серверы в NHibernate. Это позволяет вам лениво загружать их. Исключение указывает, что вы используете один из этих прокси в двух открытых сеансах. Это означает, что вы загружаете объект за один сеанс и пытаетесь сохранить его в другом. Если это необходимо, закройте первый сеанс, прежде чем использовать следующий. Я бы рекомендовал использовать шаблон UnitOfWork для предотвращения такого поведения.

+0

Я убедился, что в разное время сеанс имеет тот же самый идентификатор сеанса, что и у DataSessionContext.Session – user3260672

+0

К сожалению, у NHibernate есть другое мнение ^^ Вы можете попробовать [NHibernate Profiler] (https://www.hibernatingrhinos.com/products/nhprof), чтобы проверить открытые сеансы. Он бесплатный в течение 30 дней и imho является важным инструментом для каждого разработчика, который работает с NHibernate. – Rabban

+0

спасибо @Rabban – user3260672