如何使用NHibernate CreateCriteria进行可能的空值连接?

时间:2013-01-29 22:57:17

标签: c# nhibernate

NHibernate版本:3.3.1

原始查询如下。

List<PostInstruction> instructions = PostInstruction.Query(
    Restrictions.Eq("Campaign", campaign),
    Restrictions.In("Status", new PostInstructionStatus[] { 
                PostInstructionStatus.Pending, 
                PostInstructionStatus.Finished 
                }),
    Restrictions.Or(
        Restrictions.Gt("DateCreated", DateTime.UtcNow - TimeSpan.FromMinutes(15)),
        Restrictions.IsNotNull("Post")
        )
    );

我们只将它用于Count功能,所以我将其转换为仅返回计数,但遇到了问题。我必须做两个单独的查询才能计算空的Post值。有没有办法在一个查询中执行以下操作?

    public static int CountByCampaignCity(Campaign campaign, City city)
    {
        int finished, pending;

        using (ISession session = DataAccess.SessionFactory.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            try
            {
                Type objectType = typeof(PostInstruction);
                ICriteria criteria = session.CreateCriteria(objectType);

                criteria.Add(Restrictions.Eq("Campaign", campaign));
                criteria.Add(Restrictions.Eq("City", city));
                criteria.Add(Restrictions.Eq("Status", PostInstructionStatus.Finished));

                criteria.CreateCriteria("Post").Add(Restrictions.In("Status", new PostStatus[] { PostStatus.Pending, PostStatus.Live }));
                criteria.SetProjection(Projections.CountDistinct("Id"));

                finished = int.Parse(criteria.UniqueResult().ToString());
            }
            catch
            {
                if (transaction != null)
                    transaction.Rollback();

                throw;
            }
        }

        using (ISession session = DataAccess.SessionFactory.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            try
            {
                Type objectType = typeof(PostInstruction);
                ICriteria criteria = session.CreateCriteria(objectType);

                criteria.Add(Restrictions.Eq("Campaign", campaign));
                criteria.Add(Restrictions.Eq("City", city));
                criteria.Add(Restrictions.Eq("Post", null));
                criteria.Add(Restrictions.Eq("Status", PostInstructionStatus.Pending));
                criteria.Add(Restrictions.Gt("DateCreated", DateTime.UtcNow - TimeSpan.FromMinutes(15)));
                criteria.SetProjection(Projections.CountDistinct("Id"));

                pending = int.Parse(criteria.UniqueResult().ToString());
            }
            catch
            {
                if (transaction != null)
                    transaction.Rollback();

                throw;
            }
        }

        return pending + finished;
    }

1 个答案:

答案 0 :(得分:0)

使用QueryOver,您应该可以执行以下操作:

var instructionsCount = session.QueryOver<PostInstruction>()
    .Select(Projections.Count<PostInstruction>(pi => pi.Id))
    .Where(pi => pi.Campaign == campaign && pi.City == city && (pi.Post == PostStatus.Pending || pi.Post == PostStatus.Live || pi.Post == null)); //Add your other conditions

Console.WriteLine(instructionsCount.SingleOrDefault<int>());