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即可。也可以用其他的任意字符串,只要能唯一的标识出不同的自增量就可以。

  • 相关阅读:
    540 Single Element in a Sorted Array 有序数组中的单一元素
    539 Minimum Time Difference 最小时间差
    538 Convert BST to Greater Tree 把二叉搜索树转换为累加树
    537 Complex Number Multiplication 复数乘法
    535 Encode and Decode TinyURL 编码和解码精简URL地址
    532 K-diff Pairs in an Array 数组中差为K的数对
    530 Minimum Absolute Difference in BST 二叉搜索树的最小绝对差
    529 Minesweeper 扫雷游戏
    526 Beautiful Arrangement
    1.5 函数
  • 原文地址:https://www.cnblogs.com/Elvin/p/1769424.html
Copyright © 2011-2022 走看看