NHibernate - 如何一次更新多个布尔字段

时间:2011-12-01 22:21:46

标签: nhibernate

我在我正在构建的Web应用程序中使用NHibernate。用户可以下标到零个或多个邮件列表(总共有8个)。这在屏幕上显示,每个邮件列表都有一个复选框。

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

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

通过NHibernate执行此更新的最简洁方法是什么,以便我可以单程往返数据库? 提前致谢

JP

2 个答案:

答案 0 :(得分:2)

NHibernate可能无法以您在上面显示的方式更新mail_subscriptions,但它可以使用批量查询在数据库的单次往返中执行此操作。

此示例使用SubscriptionsHasMany视为Component,但如果映射只是普通HasMany,则可以使用大致相同的技术。我还假设每个用户已经在mail_subscriptions表格中为每个邮件列表设置了行false subscribed

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

答案 1 :(得分:2)

我认为您寻求的NHibernate功能称为可执行DML

Ayende有一篇博客文章,在http://ayende.com/blog/4037/nhibernate-executable-dml给出了一个例子。

根据您的实体名称及其属性,并假设您有一个名为session的ISession实例变量,您需要执行以下类似的HQL查询:

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

现在,我已经说过,我认为在您描述的用例中(在单个聚合根上更新集合中的少数条目),不需要使用可执行DML。 Mark Perry有正确的想法 - 你应该简单地修改相应实体上的布尔值并以通常的方式刷新会话。如果ADO.NET批处理配置正确,则子条目将导致在单个数据库调用中将多个更新语句发送到RDBMS。