Nhibernate Criteria: 'select max(id)…'

后端 未结 3 1298
攒了一身酷
攒了一身酷 2021-01-02 08:28

Can I use a Criteria to execute a t-sql command to select the max value for a column in a table?

\'select @cus_id = max(id) + 1 from customers\'

Ta

O

3条回答
  •  执念已碎
    2021-01-02 08:51

    Best approach is to make additional Sequences table. Where you can maintain sequence target and value.

    public class Sequence : Entity
    {
    
        public virtual long? OwnerId { get; set; }
    
        public virtual SequenceTarget SequenceTarget { get; set; }
    
        public virtual bool IsLocked { get; set; }
    
        public virtual long Value { get; set; }
    
        public void GenerateNextValue()
        {
            Value++;
        }
    
    }
    
    public class SequenceTarget : Entity
    {
    
        public virtual string Name { get; set; }
    
    }
    
    public long GetNewSequenceValueForZZZZ(long ZZZZId)
    {
        var target =
            Session
            .QueryOver()
            .Where(st => st.Name == "DocNumber")
            .SingleOrDefault();
    
        if (target == null)
        {
            throw new EntityNotFoundException(typeof(SequenceTarget));
        }
    
        return GetNewSequenceValue(ZZZZId, target);
    }
    
    protected long GetNewSequenceValue(long? ownerId, SequenceTarget target)
    {
        var seqQry =
           Session
           .QueryOver()
           .Where(seq => seq.SequenceTarget == target);
        if (ownerId.HasValue)
        {
           seqQry.Where(seq => seq.OwnerId == ownerId.Value);
        }
    
        var sequence = seqQry.SingleOrDefault();
    
        if (sequence == null)
        {
           throw new EntityNotFoundException(typeof(Sequence));
        }
    
        // re-read sequence, if it was in session
        Session.Refresh(sequence);
    
        // update IsLocked field, so we acuire lock on record
        // configure dynamic update , so only 1 field is being updated
        sequence.IsLocked = !sequence.IsLocked;
        Session.Update(sequence);
        // force update to db
        Session.Flush();
        // now we gained block - re-read record.
        Session.Refresh(sequence);
    
        // generate new value
        sequence.GenerateNextValue();
        // set back dummy filed
        sequence.IsLocked = !sequence.IsLocked;
        // update sequence & force changes to DB
        Session.Update(sequence);
        Session.Flush();
    
        return sequence.Value;
    }
    

    OwnerId - when you need to maintain different sequences for same entity, based on some kind of owner. For example you need to maintain numbering for document within contract, then OwnerId will be = contractId

提交回复
热议问题