简体   繁体   English

如何在C#中比较/转换SQL rowversion字段数据

[英]How compare/cast SQL rowversion field data in C#

I have two records in my student table with a row-version field. 我的学生表中有两条带有行版本字段的记录。 I am creating the object of that record as student class in my C# code. 我在C#代码中创建该记录的对象作为学生类。

My question are: 我的问题是:

  1. In which C# compatible datatype is rowversion data cast? 哪个C#兼容数据类型是rowversion数据转换?
  2. How do I compare rowversion of two records and find which one is the latest in C#? 如何比较两个记录的rowversion并找出哪个是最新的C#?

One way to find the latest rowversion is to use the StructuralComparer 找到最新rowversion的一种方法是使用StructuralComparer

var r1 = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00};
var r2 = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF};

bool r1_is_newer = StructuralComparisons.StructuralComparer.Compare(r1, r2) > 0;

A benefit of the structural comparisons is that they automatically deal with NULL s 结构比较的好处是它们自动处理NULL

Regarding use of the BitConverter . 关于BitConverter使用。 If the above byte arrays were converted to UInt64 using the BitConverter , you'd end up with very high numbers and the comparison is meaningless (as the rowversion changes by one, the uint64 converted number changes by around 2^56) 如果使用BitConverter将上述字节数组转换为UInt64 ,则最终会得到非常高的数字并且比较没有意义(因为rowversion改变了一个,uint64转换后的数字改变了大约2 ^ 56)

If you'd like to sprinkle some LINQ over it to make it extra slow, you can use 如果你想在它上面洒一些LINQ以使它变得特别慢,你可以使用它

bool r1_is_newer = 
  Enumerable.Zip(r1, r2, (b1, b2) => new { b1, b2 })
  .SkipWhile(item => item.b1 == item.b2)
  .Take(1).Any(item => item.b1 > item.b2);

rowversion is binary(8) , and will be returned as a byte[] if you use SqlCommand / SqlDataReader . rowversionbinary(8) ,如果你使用SqlCommand / SqlDataReader ,它将作为byte[]返回。 If you use EF 4.1, the corresponding property will also be byte[] . 如果使用EF 4.1,则相应的属性也将为byte[]

You could use BitConverter to convert to UInt64 and then compare. 您可以使用BitConverter转换为UInt64然后进行比较。 You could also return the rowversion cast as bigint from SQL Server, which would appear as a long in C#. 您还可以从SQL Server返回rowversion强制转换为bigint ,这在C#中显示为long In either case, the larger value would have been created later. 在任何一种情况下,较大的值都将在以后创建。

In my own tests, I've seen that rowversion starts at a small, positive value (not 0). 在我自己的测试中,我已经看到rowversion从一个小的正值开始(不是0)。 If you do cast to bigint , you'll have to consider what will happen when it reaches 2^64 . 如果你投射到bigint ,你将不得不考虑到达2^64时会发生什么。 In my case, it's not something I have to worry about. 就我而言,这不是我必须担心的事情。 If you think that will happen in your database, then you'll have to add logic to handle that in your comparison, or just stick with BitConverter.ToUInt64 . 如果您认为这将在您的数据库中发生,那么您将不得不在比较中添加逻辑来处理它,或者只是坚持使用BitConverter.ToUInt64

Also, be careful if your rowversion column accepts NULL ; 另外,请注意rowversion列是否接受NULL ; You'll have to account for that if it does. 如果有的话,你必须考虑到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM