Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
NHibernate-使用固定值更新多行的选定字段_Hibernate_Nhibernate_Batch Updates - Fatal编程技术网

NHibernate-使用固定值更新多行的选定字段

NHibernate-使用固定值更新多行的选定字段,hibernate,nhibernate,batch-updates,Hibernate,Nhibernate,Batch Updates,如何将以下SQL查询转换为NHibernate UPDATE MyTable SET Field1 = "NewValue1", Field2 = "NewValue2" WHERE Field3 = FilterValue 假设MyTable包含大量记录,并且上面的语句会影响大量记录。它有50个字段(列),其中一些字段包含长字符串或对其他表的引用,我将避免不必要地加载/更新这些字段 我现在的实施方式如下: entities = nhSession.Qu

如何将以下SQL查询转换为NHibernate

UPDATE MyTable
SET Field1 = "NewValue1",
Field2 = "NewValue2"
WHERE Field3 = FilterValue
假设
MyTable
包含大量记录,并且上面的语句会影响大量记录。它有50个字段(列),其中一些字段包含长字符串或对其他表的引用,我将避免不必要地加载/更新这些字段

我现在的实施方式如下:

entities = nhSession.QueryOver<T>().Where(whereJunction).List();
nhSession.SetBatchSize(batchSize);
transaction = nhSession.BeginTransaction();
foreach(entity in entities)
{
    //Modify entity here...
    //nhSession.Update(entity);//No need to call this. Commit() will do.
}
transaction.Commit();
entities=nhSession.QueryOver().Where(whereJunction.List();
nhSession.SetBatchSize(批量大小);
事务=nhSession.BeginTransaction();
foreach(实体中的实体)
{
//在此处修改实体。。。
//nhSession.Update(entity);//无需调用此函数。Commit()即可。
}
Commit();
尽管批处理有助于提高性能,但这种方法有以下缺点:

  • 执行多个语句最终会降低性能
  • foreach
    循环
  • 使用
    nhSession.Flush()
优点是,更新会反映在缓存中

另一种方法是
HQL
,出于以下原因,我不考虑这种方法:

  • 弦;我不太爱他们。这就是我切换到
    ORM
    的原因之一
  • 不是强类型的。重构是困难的
  • 更新不会反映在缓存中
  • 我不确定这是否符合UoW(NHibernate交易)
还有一种方法是我不想使用的原始
SQL
。我想坚持下去

参考资料: 当前位置问题和所有答案都表明了我前面提到的方法

:和我上面提到的一样

:和我上面提到的一样


注意:我还添加了“hibernate”标签,假设NHibernate也提供类似的解决方案;顺便说一下,它们是双胞胎。

我们必须学会使用C#(POCO)实体和强类型代码,或者使用HQL

如果我们想保持实体(映射对象)带来的舒适感,上面的代码(带问题的代码)将完成这项工作

entities = nhSession... // load and TRANSFORM to C# objects
foreach(entity in entities)
{
    //Modify entity here...
}
如果我们准备好使用HQL(字符串,甚至是我们的自定义字符串生成器来实现更大程度的自动化),我们可以从NHibernate内置API中获益匪浅:

作者:Ayende 例如,如下所示:

我们可以在不加载任何数据的情况下进行更新

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
string hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName";
int updatedEntities = s.CreateQuery( hqlUpdate )
        .SetString( "newName", newName )
        .SetString( "oldName", oldName )
        .ExecuteUpdate();
tx.Commit();
session.Close();

其他

您现在可以将Linq与NHibernate一起使用

//
// Summary:
//     Update all entities selected by the specified query. The update operation is
//     performed in the database without reading the entities out of it.
//
// Parameters:
//   source:
//     The query matching the entities to update.
//
//   expression:
//     The update setters expressed as a member initialization of updated entities,
//     e.g. x => new Dog { Name = x.Name, Age = x.Age + 5 }. Unset members are ignored
//     and left untouched.
//
// Type parameters:
//   TSource:
//     The type of the elements of source.
//
// Returns:
//     The number of updated entities.
public static int Update<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, TSource>> expression);
//
//总结:
//更新指定查询选择的所有实体。更新操作已完成
//在数据库中执行,而不从中读取实体。
//
//参数:
//资料来源:
//匹配要更新的实体的查询。
//
//表达方式:
//表示为已更新实体的成员初始化的更新设置器,
//例如,x=>新狗{Name=x.Name,Age=x.Age+5}。未设置的成员将被忽略
//没有动过。
//
//类型参数:
//t来源:
//源的元素的类型。
//
//返回:
//更新实体的数量。
公共静态int更新(此IQueryable源、表达式);
在你的情况下,这意味着:

session.Query<MyTable>()
            .Where(i => i.Field3 == FilterValue)
            .Update(i => new MyTable { Field1 = "NewValue1", Field2 = "NewValue2" });
session.Query()
.其中(i=>i.Field3==FilterValue)
.Update(i=>newmytable{Field1=“NewValue1”,Field2=“NewValue2”});

从您的代码中,
session.Query()
将加载包含所有50个字段(列)的完整实体,其中一些字段包含长字符串。我说的对吗?@AmitJoshi-no就是这样,它现在只生成一个更新查询!您还可以查看执行批量删除的.Delete()。我们刚刚迁移了一个项目来使用它们,相信我,我们很高兴。