NHibernate的:System.Argument例外:具有相同的密钥项目已被添加 [英] NHibernate: System.Argument Exception : An item with the same key has already been added
问题描述
- MVC 2.0
- Fluent version 1.1.0.685
- NHibernate版本2.1.2.4000
$ b
异常:System.ArgumentException:
具有相同键的项目已经添加了
。
堆栈跟踪:在
System.Collections.Generic.Dictionary <$ c
NHibernate.Util.ThreadSafeDictionary 2.Add(TKey
key,TValue value
key,TValue value,Boolean add) )
NHibernate.SqlTypes.SqlTypeFactory.GetTypeWithLen [T](Int32
length,TypeWithLenCreateDelegate
createDelegate)at
NHibernate.Type.EnumStringType..ctor(Type
enumClass,Int32长度)
我正在使用存储库模型。这是我的资源库类。
public sealed class Repository< T> :IRepository< T>其中T:CoreObjectBase
{
#region IRepository< T>成员
private ISession Session
{
get
{
return new SessionHelper()。GetSession();
}
}
public IQueryable< T> GetAll()
{
return(来自Session.Linq< T>()中的实体select实体);
}
public T GetById(int id)
{
return Session.Get< T>(id);
$ b public void Save(params T [] entities)
{
using(ITransaction tx = Session.BeginTransaction())
{
for(int x = 0; x {
var entity = entities [x];
entity.Validate();
Session.SaveOrUpdate(entities [x]);
if(x == entities.Count() - 1 ||(x!= 0&& x%20 == 0))// 20是批量大小
{
Session.Flush();
Session.Clear();
}
}
tx.Commit();
$ b $ public void SaveWithDependence< K>(T entity,K dependent)其中K:CoreObjectBase
{
entity.Validate();
dependant.Validate();
using(ITransaction tx = Session.BeginTransaction())
{
Session.SaveOrUpdate(entity);
Session.SaveOrUpdate(依赖);
tx.Commit();
$ b $ public void Save(T entity)
{
entity.Validate();
using(ITransaction tx = Session.BeginTransaction())
{
Session.SaveOrUpdate(entity);
tx.Commit();
$ b $ public void删除(T实体)
{
using(ITransaction tx = Session.BeginTransaction())
{
Session.Delete(entity);
tx.Commit();
$ b public T GetOne(QueryBase< T> query)
{
var result = query.SatisfyingElementFrom(Session.Linq< T> ());
返回结果;
// return query.SatisfyingElementFrom(Session.Linq< T>());
}
public IQueryable< T> GetList(QueryBase< T> query)
{
return query.SatisfyingElementsFrom(Session.Linq< T>
}
///< summary>
///从一级缓存中删除特定对象,以便从数据库中刷新
///< / summary>
///< param name =entity>< / param>
public void Evict(T entity)
{
Session.Evict(entity);
}
#endregion
}
public sealed class SessionHelper
{
private static ISessionFactory _sessionFactory;
private static ISession _currentSession;
public ISession GetSession()
{
ISessionFactory factory = getSessionFactory();
ISession session = getExistingOrNewSession(factory);
返回会话;
$ b $ private ISessionFactory getSessionFactory()
{
if(_sessionFactory == null)
{
_sessionFactory = BuildSessionFactory();
}
return _sessionFactory;
$ b $ private ISessionFactory BuildSessionFactory()
{
return Fluentntly.Configure()。Database(
FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005
.ConnectionString(c => c
.FromConnectionStringWithKey(MyDatabase))
.AdoNetBatchSize(20))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf< SessionHelper>())
.BuildSessionFactory();
$ b $ private ISession getExistingOrNewSession(ISessionFactory factory)
{
if(HttpContext.Current!= null)
{
ISession session = GetExistingWebSession();
if(session == null)
{
session = openSessionAndAddToContext(factory);
else if(!session.IsOpen)
{
session = openSessionAndAddToContext(factory);
}
返回会话;
if(_currentSession == null)
{
_currentSession = factory.OpenSession();
}
else if(!_currentSession.IsOpen)
{
_currentSession = factory.OpenSession();
}
return _currentSession;
$ b $ public ISession GetExistingWebSession()
{
返回HttpContext.Current.Items [GetType()。FullName]作为ISession;
$ b $ private ISession openSessionAndAddToContext(ISessionFactory factory)
{
ISession session = factory.OpenSession();
HttpContext.Current.Items.Remove(GetType()。FullName);
HttpContext.Current.Items.Add(GetType()。FullName,session);
返回会话;
$ b $ p $任何想法或建议,以避免这个问题?解决方案问题是, SessionHelper
不是线程安全的。它可能会建立几个会话工厂(这是一个不好的Singleton实现),这反过来可能会导致你看到的错误。
我推荐使用
I'm getting a sporadic error that is difficult to reproduce. My first guess is that somehow I have a leaking nhibernate session, however when I ran the nhibernate profiler, I didn't see much out of the ordinary.
- MVC 2.0
- Fluent version 1.1.0.685
- NHibernate version 2.1.2.4000
Exception: System.ArgumentException :
An item with the same key has already
been added.
Stack Trace: at
System.Collections.Generic.Dictionary2.Insert(TKey
key, TValue value, Boolean add) at
NHibernate.Util.ThreadSafeDictionary
2.Add(TKey
key, TValue value) at
NHibernate.SqlTypes.SqlTypeFactory.GetTypeWithLen[T](Int32
length, TypeWithLenCreateDelegate
createDelegate) at
NHibernate.Type.EnumStringType..ctor(Type
enumClass, Int32 length)
I am using a repository model. Here's my repository class.
public sealed class Repository<T> : IRepository<T> where T : CoreObjectBase
{
#region IRepository<T> Members
private ISession Session
{
get
{
return new SessionHelper().GetSession();
}
}
public IQueryable<T> GetAll()
{
return (from entity in Session.Linq<T>() select entity);
}
public T GetById(int id)
{
return Session.Get<T>(id);
}
public void Save(params T[] entities)
{
using (ITransaction tx = Session.BeginTransaction())
{
for (int x = 0; x < entities.Count(); x++)
{
var entity = entities[x];
entity.Validate();
Session.SaveOrUpdate(entities[x]);
if (x == entities.Count() - 1 || (x != 0 && x % 20 == 0)) //20 is the batch size
{
Session.Flush();
Session.Clear();
}
}
tx.Commit();
}
}
public void SaveWithDependence<K>(T entity, K dependant) where K : CoreObjectBase
{
entity.Validate();
dependant.Validate();
using (ITransaction tx = Session.BeginTransaction())
{
Session.SaveOrUpdate(entity);
Session.SaveOrUpdate(dependant);
tx.Commit();
}
}
public void Save(T entity)
{
entity.Validate();
using (ITransaction tx = Session.BeginTransaction())
{
Session.SaveOrUpdate(entity);
tx.Commit();
}
}
public void Delete(T entity)
{
using (ITransaction tx = Session.BeginTransaction())
{
Session.Delete(entity);
tx.Commit();
}
}
public T GetOne(QueryBase<T> query)
{
var result = query.SatisfyingElementFrom(Session.Linq<T>());
return result;
//return query.SatisfyingElementFrom(Session.Linq<T>());
}
public IQueryable<T> GetList(QueryBase<T> query)
{
return query.SatisfyingElementsFrom(Session.Linq<T>());
}
/// <summary>
/// remove the sepcific object from level 1 cache so it can be refreshed from the database
/// </summary>
/// <param name="entity"></param>
public void Evict(T entity)
{
Session.Evict(entity);
}
#endregion
}
And here is my session helper, adapted from this.
public sealed class SessionHelper
{
private static ISessionFactory _sessionFactory;
private static ISession _currentSession;
public ISession GetSession()
{
ISessionFactory factory = getSessionFactory();
ISession session = getExistingOrNewSession(factory);
return session;
}
private ISessionFactory getSessionFactory()
{
if (_sessionFactory == null)
{
_sessionFactory = BuildSessionFactory();
}
return _sessionFactory;
}
private ISessionFactory BuildSessionFactory()
{
return Fluently.Configure().Database(
FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005
.ConnectionString(c => c
.FromConnectionStringWithKey("MyDatabase"))
.AdoNetBatchSize(20))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionHelper>())
.BuildSessionFactory();
}
private ISession getExistingOrNewSession(ISessionFactory factory)
{
if (HttpContext.Current != null)
{
ISession session = GetExistingWebSession();
if (session == null)
{
session = openSessionAndAddToContext(factory);
}
else if (!session.IsOpen)
{
session = openSessionAndAddToContext(factory);
}
return session;
}
if (_currentSession == null)
{
_currentSession = factory.OpenSession();
}
else if (!_currentSession.IsOpen)
{
_currentSession = factory.OpenSession();
}
return _currentSession;
}
public ISession GetExistingWebSession()
{
return HttpContext.Current.Items[GetType().FullName] as ISession;
}
private ISession openSessionAndAddToContext(ISessionFactory factory)
{
ISession session = factory.OpenSession();
HttpContext.Current.Items.Remove(GetType().FullName);
HttpContext.Current.Items.Add(GetType().FullName, session);
return session;
}
}
Any ideas or suggestions to avoid this issue?
解决方案 Problem is, that SessionHelper
isn't thread-safe. It will potentially build several session factories (it's a bad implementation of Singleton), which in turn probably causes the error you're seeing.
I recommend using SharpArchitecture as guidance instead.
这篇关于NHibernate的:System.Argument例外:具有相同的密钥项目已被添加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!