Binary(16)字段截断了Guid的尾随零 [英] Binary(16) field Is truncating Guid's trailing zeros

查看:73
本文介绍了Binary(16)字段截断了Guid的尾随零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,我有一个 byte [] 字段,称为UniqueId.我将此字段存储为SQL Server数据库(EF6)中的Binary(16).

In C#, I have a byte[] field called UniqueId. I store this field as a Binary(16) in a SQL Server database (EF6).

我注意到有时候,存储的guid是15字节而不是16字节.从数据库检索值后执行 var guid = new Guid(uniqueId)时,这将导致以下异常:

I have noticed that sometimes, the stored guid is 15 bytes instead of 16 bytes. This causes the following exception when I do var guid = new Guid(uniqueId) after retrieving the value from the db:

System.ArgumentException:GUID的字节数组必须正好为16长字节.

System.ArgumentException : Byte array for GUID must be exactly 16 bytes long.

在对此进行调查之后,我注意到,只要我生成的guid在十六进制的末尾包含"00",SQL就会将其截断!

After investigating this, I noticed that whenever my generated guid contains "00" at the end of the hex, SQL truncates it!

示例:

生成的Guid(通过Guid.NewGuid): FF96F954777E8941A04774CD157C5C00(16字节)

Generated Guid (via Guid.NewGuid): FF96F954777E8941A04774CD157C5C00 (16 bytes)

在SQL Server中存储二进制(16):0xFF96F954777E8941A04774CD157C5C(15字节)

Stored Binary(16) in SQL Server: 0xFF96F954777E8941A04774CD157C5C (15 bytes)

如果您注意到,末尾的 00 将被截断.结果,如果我查询此字段并尝试将其字节转换为Guid,则会得到 System.ArgumentException .

If you notice, the 00 at the end is truncated. As a result, if I query this field and try to convert its bytes to a Guid, I'll get a System.ArgumentException.

还有其他人遇到这个问题吗?解决方法是什么?我正在考虑 Guid 的包装器,该包装器将继续生成guid,直到它没有尾随零为止,但这似乎很麻烦.

Is anybody else experiencing this problem? What is the workaround? I am thinking about a wrapper for Guid that keeps generating guids until it doesn't have trailing zeros, but that seems hacky.

更新1:由于你们的要求,我运行了SQL事件探查器,这是由EF(节略版)生成的SQL:

Update 1: Since you guys requested it, I ran the SQL profiler, and this is the SQL generated by EF (abridged version):

exec sp_executesql N'INSERT [dbo].[customers]([UniqueId])
VALUES (@0)',N'@0 varbinary(max)',@0=0xFF96F954777E8941A04774CD157C5C00

推荐答案

如果列的 ANSI_PADDING 设置为 BINARY(16)中看到此行为> OFF ,并且该列允许 NULL (演示).

You see this behaviour with BINARY(16) if the ANSI_PADDING setting for the column is OFF and the column allows NULL (demo).

修复该问题最好是更改表定义,以便该列使用 uniqueidentifier 数据类型或至少启用 ANSI_PADDING .

Fixing it would ideally involve changing the table definition so the column is using uniqueidentifier datatype or at least has ANSI_PADDING on.

要更改 ANSI_PADDING 的语义,将涉及 SET ANSI_PADDING ON ,然后添加一个新的 binary(16)列-从旧列填充它然后拖放并重命名.这是您的应用程序可以忍受列的可能重新排序,如果它不能应对这种重新排序并且 UniqueId 不是表中的最后一列,则需要创建一个新表并进行迁移所有数据.

To change the ANSI_PADDING semantics will involve SET ANSI_PADDING ON then adding a new binary(16) column - populating it from the old column and then a drop and rename. And this is if your application can tolerate a possible reordering of columns, if it can't cope with this reordering and UniqueId is not the last column in the table you will need to create a new table and migrate all data across.

这篇关于Binary(16)字段截断了Guid的尾随零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆