2015-05-09 32 views
0

有一个没有关系的表和一个整数主键。使用NHibernate我想重新填充表在一个事务中,像这样:NHibernate清除/截断表和重新填充单个事务

  • openTrans
  • 删除所有行
  • 插入新行(很多人都会有相同的ID与以前删除)
  • commitTrans

然而,NHibernate抛出'具有相同标识符值的不同对象已与会话相关联',我尝试保存新实体。这是有道理的,因为我实际上已经创建了一个具有相同Id的新实体。我尝试通过覆盖实体类上的GetHashCode和Equals来欺骗NHibernate,以便两个具有相同ID的对象“相等”,但我得到相同的结果。

我可以采取的另一种方法是更新已存在的实体,删除不在新数据集中的现有实体并添加新实体,但这是我希望避免的很多工作,因为故事只是重新填充桌子。我当然可以在两个会话中做到这一点,但我希望整个操作都是原子的。

+0

你能不能不要在此处使用NHibernate的? –

+0

我正在使用NHibernate。我现在已经实施了第二个选项,它给了我需要的确切行为,尽管需要更多的努力。 –

+0

使用createsql和truncate删除行。然后插入。那样有用吗? – Rippo

回答

2

选项1

session.Clear(); // to get rid associations of the objects in memory 
session.CreateQuery("delete from MyClass").ExecuteUpdate(); 
foreach(var entity in CreateNew()) 
    session.Save(entity); 

选项2

session.CreateQuery("delete from MyClass where Id not in (:ids)") 
    .SetParameterList("ids", newIds) 
    .ExecuteUpdate(); 
foreach (var id in newIds) 
{ 
    var entity = session.Get<MyClass>(id); // returns the cached instance if present or the database instance or null if non existant 
    if (entity == null) 
    { 
     entity = new MyClass { Id = id }; 
     session.Save(entity); 
    } 
    Populate(entity); 
} 

选项3

var newEntities = CreateNew(); 

session.CreateQuery("delete from MyClass where Id not in (:ids)") 
    .SetParameterList("ids", newEntities.Select(x => x.Id).ToArray()) 
    .ExecuteUpdate(); 

foreach(var entity in newEntities) 
    session.Merge(entity); // will get the object with the same id and copies over properties over 
+0

是查询字符串文字还是NHibernate翻译它的目标数据库平台?我假设字符串的格式可能会因不同的平台而有所不同。我想尽可能保持代码平台不可知。 –

+0

文字是HQL,它是对象查询语言和平台无关的。我认为'删除MyClass的地方不在(:IDS)'也应该工作 – Firo

相关问题