3

我有一个具有以下属性的对象


GID
ID
代码
名称

有些客户不想输入代码,所以最初的计划是将 ID 放在代码中,但是 orm 的基本对象不同,所以我就像搞砸了......

我的计划是将####-#### 完全随机的值放入代码中,我怎样才能生成类似 Windows 7 串行生成器类型的东西,但在这种情况下你会做什么?

4

3 回答 3

3

你想要一个随机值,还是一个唯一值?

随机!=独特

请记住,随机仅说明生成相同值的概率,或再次生成相同值的概率。随着时间的增加,生成先前值的可能性会增加 - 几乎可以确定。你需要哪个?

就个人而言,我建议只使用带有某些上下文的 Guid [请参阅下面最简单的部分]。我还提供了一些其他建议,因此您可以根据自己的情况进行选择。


最简单的

如果代码是一个无界字符串[即可以是任何长度],生成唯一代码的最简单的半可读方法将是

OrmObject ormObject= new OrmObject ();
string code = string.
    Format ("{0} [{1}]", ormObject.Name, Guid.NewGuid ()).
    Trim ();
// generates something like
// "My Product [DA9190E1-7FC6-49d6-9EA5-589BBE6E005E]"

您可以替换ormObject.Name任何可区分的字符串。我通常会使用typeof (objectInstance.GetType ()).Name,但这只有在 OrmObject 是一个基类时才有效,如果它是一个用于所有东西的具体类,它们都会以相似的标签结束。重点是添加一些用户上下文,例如在@Yuriy Faktorovich 引用的wtf 文章中- 用户可以阅读一些内容。


随机的

我在一两天前回复了关于随机数生成的问题。与其说生成数字不如围绕生成器构建一个简单灵活的框架来提高代码和数据的质量,这应该有助于简化您的源代码

如果你读到了,你可以很容易地写一个扩展方法,比如

public static class IRandomExtensions
{
    public static CodeType GetCode (this IRandom random)
    {
        // 1. get as many random bytes as required
        // 2. transform bytes into a 'Code'
        // 3. bob's your uncle
        ...
    }
}

    // elsewhere in code
    ...
    OrmObject ormObject = new OrmObject ();
    ormObject.Code = random.GetCode ();
    ...

要实际生成一个值,我建议IRandom使用一个实现来实现一个接口System.Security.Cryptography.RNGCryptoServiceProvider。所述实现将生成 X 个随机字节的缓冲区,并根据需要分配尽可能多的缓冲区,并在耗尽时重新生成流。

此外-我不知道为什么我一直在写,我想这个问题真的很有趣!- 如果 CodeType 是字符串并且你想要一些可读的东西,你可以只取所说的随机字节并通过 Base64 转换将它们变成“看似”可读的字符串

public static class IRandomExtensions
{
    // assuming 'CodeType' is in fact a string
    public static string GetCode (this IRandom random)
    {
        // 1. get as many random bytes as required
        byte[] randomBytes; // fill from random
        // 2. transform bytes into a 'Code'
        string randomBase64String = 
            System.Convert.ToBase64String (randomBytes).Trim ("=");
        // 3. bob's your uncle
        ...
    }
}

记住

随机!=独特

你的价值观重复。最终。


独特

关于你的问题,你需要问自己很多问题。

  1. 所有Code值都必须是唯一的吗?[如果没有,你太努力了]
  2. 什么类型Code?[如果是任意长度的字符串,请使用完整的 Guid]
  3. 这是一个分布式应用程序吗?[如果没有,请使用上面@LBushkin 建议的 DB 值]
  4. 如果是分布式应用程序,客户端应用程序可以生成并提交这些对象的实例吗?[如果是这样,那么你需要一个全球唯一的标识符,Guids 是一个肯定的选择]

我相信你有更多的限制,但这是你遇到像你自己的问题时需要执行的那种查询的例子。从这些问题中,你会想出一系列的约束。这些约束将告知您的设计。

希望这可以帮助 :)

顺便说一句,如果您发布有关您的问题的更多详细信息 [即限制条件],您将收到质量更好的解决方案。同样,什么是 Type Code,有长度限制吗?格式限制?性格限制?

Arg,最后一次编辑,我发誓。如果您最终使用了 Guid,您可能希望混淆它,甚至通过在 base64 中编码它们来“压缩”它们的表示 - 类似于上面对随机数的 base64 转换。

public static class GuidExtensions
{
    public static string ToBase64String (this Guid id)
    {
        return System.Convert.
            ToBase64String (id.ToByteArray ()).
            Trim ("=");
    }
}

与截断不同,base64 转换不是有损转换。当然,上面的修剪在完全 base64 扩展的上下文中是有损的 - 但=只是填充,转换引入额外信息,而不是原始 Guid 数据的一部分。如果你想从这个 base64 转换值返回到 Guid,那么你将不得不重新填充你的 base64 字符串,直到它的长度是 4 的倍数 - 不要问,如果你有兴趣,只需查找 base64 :)

于 2009-10-29T14:15:50.183 回答
1

您可以使用以下命令生成 Guid:

Guid.NewGuid().ToString();

它会给你类似的东西:

788E94A0-C492-11DE-BFD4-FCE355D89593

于 2009-10-29T13:52:37.003 回答
0

使用数据库中的自动编号列或排序器生成唯一的代码编号。几乎所有现代数据库都支持以一种或另一种形式自动生成的数字。查看您的数据库支持的内容。

数据库中的自动编号/序列器值保证是唯一的,并且获取成本相对较低。如果您想避免将完全连续的数字分配给代码,您可以将多个排序器值填充并连接在一起。

于 2009-10-29T14:06:04.463 回答