【问题标题】:NHibernate - How do I update more than one boolean field at a timeNHibernate - 如何一次更新多个布尔字段
【发布时间】:2011-12-03 23:33:15
【问题描述】:

我正在构建的 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 执行此更新的最简洁方法是什么,以便我可以单次往返数据库? 提前致谢

日本

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    NHibernate 可能无法以您在上面显示的方式更新mail_subscriptions,但它可以使用批处理查询在一次往返数据库中完成。

    此示例考虑使用ComponentSubscriptions 映射为HasMany,尽管如果映射只是一个普通的HasMany,则可以使用大致相同的技术。我还假设每个用户已经在mail_subscriptions 表中为每个邮件列表设置了行,这些行设置为false for 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
    

    【讨论】:

      【解决方案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();
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-26
        • 2015-10-31
        • 2023-01-31
        • 1970-01-01
        • 1970-01-01
        • 2020-05-07
        • 2010-09-19
        • 1970-01-01
        相关资源
        最近更新 更多