zoukankan      html  css  js  c++  java
  • 如何在XPO中为非主键字段获取Int型自增量

    数据库中的一条记录,除了应有自己的唯一切不包含任何逻辑意义的主键外,常常也需要一些暴露给最终用户的,User-Friendly的唯一编号。

    例如用户、订单之类的对象,除了自己有一个可能是GUID类型的主键以外,常常还会有一个Int型的编号“用户编号”,“订单号码”。

    如果直接操作数据库,例如SQL SERVER,这是很容易的,只需要将字段设成Identity即可获得一个自增量。

    但是在XPO中,只有作为KEY(主键)的字段才有AutoGenerate属性,其他非KEY的字段都没有。同时,XPO又限定一个对象只能有一个KEY字段。(实际上System.Data.SqlClient也是不支持的)

    那如何获取一个自增量?只能靠自己动手了。

    DevExpress的Support Center中提供了一段Sample:

    http://www.devexpress.com/Support/Center/p/CQ22273.aspx

    例子中的代码稍显复杂,偶将其简化如下:

    XpoSequencer
     1     public sealed class XpoSequencer : XPBaseObject
     2     {
     3         [Key(true)]
     4         public Guid Oid;
     5         [Size(254), Indexed(Unique = true)]
     6         public string SequenceId;
     7         public int Counter;
     8         public XpoSequencer(Session session) : base(session) { }
     9         public const int MaxIdGenerationAttempts = 7;
    10         public const int MinConflictDelay = 50;
    11         public const int MaxConflictDelay = 500;
    12 
    13         public static int GetNextValue(IDataLayer dataLayer, string sequenceId)
    14         {
    15             if (dataLayer == null)
    16                 throw new ArgumentNullException("dataLayer");
    17             if (sequenceId == null)
    18                 sequenceId = string.Empty;
    19             for (int attempt = 1; ; ++attempt)
    20             {
    21                 try
    22                 {
    23                     using (Session generatorSession = new Session(dataLayer))
    24                     {
    25                         XpoSequencer generator = generatorSession.FindObject<XpoSequencer>(new OperandProperty("SequenceId"== sequenceId);
    26                         if (generator == null)
    27                         {
    28                             generator = new XpoSequencer(generatorSession);
    29                             generator.SequenceId = sequenceId;
    30                         }
    31                         generator.Counter++;
    32                         generator.Save();
    33                         return generator.Counter;
    34                     }
    35                 }
    36                 catch (LockingException)
    37                 {
    38                     if (attempt >= MaxIdGenerationAttempts)
    39                         throw;
    40                 }
    41                 if (attempt > MaxIdGenerationAttempts / 2)
    42                     Thread.Sleep(new Random().Next(MinConflictDelay, MaxConflictDelay));
    43             }
    44         }
    45     }

    只需要上面这个XpoSequencer类即可,例子中的XpoSiteId类偶没用。

    XpoSequencer 类的使用方法也很简单,例如在Order类中需要获取一个自增订单号:

            static readonly string typeName = typeof(XpoOrder).FullName;

            
    int GetMaxID()
            {
                
    return (int)XpoSequencer.GetNextValue(Session.DataLayer, typeName);
            }

    注意上面的typeName字符串,它代表了要获取自增量对象的唯一标识。在XpoSequencer中会对每一个唯一标识添加一条记录,自增量是按该记录中的值来算的。在一个项目中就可以用XpoSequencer为多个对象产生各自独立的自增量。例如换到User要用时,传入typeof(XpoUser).FullName即可。也可以用其他的任意字符串,只要能唯一的标识出不同的自增量就可以。

  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/Elvin/p/1769424.html
Copyright © 2011-2022 走看看