2011-12-01 67 views
0

我正在构建的Web应用程序中使用NHibernate。用户可以下标零个或多个邮件列表(共有8个)。这在屏幕上用每个邮件列表的复选框表示。NHibernate - 我如何一次更新多个布尔型字段

我想用NHibernate来一次更新这些。一个非常简单的SQL查询将是:

update mail_subscriptions set subscribed = true where mailing_list_id in (21,14,15,19) and user_id = 'me' 

什么是NHibernate的通过执行此更新,这样我可以做一个往返到数据库的干净的方式? 在此先感谢

JP

回答

2

NHibernate的可能无法更新你上面显示的方式mail_subscriptions但它可以使用批量查询,做到在单次往返到数据库。

此示例考虑Subscriptions映射为一个Component使用HasMany虽然大致相同的技术可以如果映射只是一个普通的HasMany使用。我还假设每个用户已经在mail_subscriptions表中为subscribed的每个邮寄列表设置为false

public class User{ 
    public virtual string Id {get; set;} 
    public virtual IList<MailSubscription> Subscriptions {get; set;} 
} 

public class MailSubscription{ 
    public virtual int ListId {get; set;} 
    public virtual bool Subscribed {get; set;} 
} 

public void UpdateSubscriptions(string userid, int[] mailingListIds){ 
    var user = session.Get<User>(userid); 
    foreach(var sub in 
     user.Subscriptions.Where(x=> mailingListIds.Contains(x.ListId))){ 
     sub.Subscribed=true; 
    } 
    session.Update(user); 
} 

现在当工作单元完成后,您应该看到像这样产生的SQL作为单次往返数据库发送。

update mail_subscriptions set subscribed=true where user_id='me' and listid=21 
update mail_subscriptions set subscribed=true where user_id='me' and listid=14 
update mail_subscriptions set subscribed=true where user_id='me' and listid=15 
update mail_subscriptions set subscribed=true where user_id='me' and listid=19 
2

我认为NHibernate的功能,你追求的是被称为可执行DML

Ayende的博客文章举例为http://ayende.com/blog/4037/nhibernate-executable-dml

根据您的实体及其属性的名称,并假设你有一个叫做会话的ISession实例变量,你将需要执行一个HQL查询类似:

session.CreateQuery("update MailSubscriptions set Subscribed = true where MailingList.Id in (21,14,15,19) and User.Id = 'me'") 
    .ExecuteUpdate(); 

现在,话虽如此,我想在你描述的用例中(更新一个集合根集合中的一些条目),不需要使用可执行的DML。马克佩里有正确的想法 - 你应该简单地修改适当的实体上的布尔值,并以通常的方式刷新会话。如果ADO.NET批处理配置适当,则子条目将导致多个更新语句在单个数据库调用中发送到RDBMS。

相关问题