Dil*_*165 5 c# linq sql-server arrays timestamp
我在Code TimeStamps的Code First Entity Framework中有一个字节数组,映射如下:
[Column(TypeName = "timestamp")]
[MaxLength(8)]
[Timestamp]
public byte[] TimeStamps { get; set; }
Run Code Online (Sandbox Code Playgroud)
上述属性等于C#中的SQL服务器"timestamp"数据类型.
在SQL服务器中,我可以轻松比较"时间戳",如下所示......
SELECT * FROM tableName WHERE timestampsColumnName > 0x000000000017C1A2
Run Code Online (Sandbox Code Playgroud)
我希望在C#或Linq Query中实现同样的功能.在这里,我编写了我的Linq查询,该查询无法正常工作.
byte[] lastTimeStamp = someByteArrayValue;
lstCostCenter.Where(p => p.TimeStamps > lastTimeStamp);
Run Code Online (Sandbox Code Playgroud)
我也尝试过BitConverter比较一个双字节数组,这个数组也无法正常工作......
lstCostCenter.Where(p => BitConverter.ToInt64(p.TimeStamps, 0) > BitConverter.ToInt64(lastTimeStamp, 0));
Run Code Online (Sandbox Code Playgroud)
如何比较C#或Linq Query中的字节数组.
注意 - 我只是不想比较两个数组,就像使用SequenceEqual或任何其他方法只是比较并返回true或false.我希望Linq查询中的比较大于>或小于<运算符,它提供了正确的数据,如SQL Server查询.
Evk*_*Evk 11
一种方法是使用IStructuralComparable,Array隐式实现:
byte[] rv1 = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01 };
byte[] rv2 = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05 };
var result = ((IStructuralComparable)rv1).CompareTo(rv2, Comparer<byte>.Default); // returns negative value, because rv1 < rv2
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因你想要使用BitConverter,你必须反转数组,因为BitConverter在大多数架构上都是小端(为了安全 - 你应该检查BitConverter.IsLittleEndian字段并且只有在它返回true时才反向).请注意,这样做效率不高.
var i1 = BitConverter.ToUInt64(rv1.Reverse().ToArray(), 0);
var i2 = BitConverter.ToUInt64(rv2.Reverse().ToArray(), 0);
Run Code Online (Sandbox Code Playgroud)
现在,如果您使用Entity Framework并且需要比较数据库查询中的时间戳,情况会有所不同,因为Entity Framework将检查您的查询表达式,以查找它理解的模式.它不理解IStructuralComparable比较(BitConverter当然也是转换),所以你必须使用技巧.声明字节数组的扩展方法,名称为Compare:
static class ArrayExtensions {
public static int Compare(this byte[] b1, byte[] b2) {
// you can as well just throw NotImplementedException here, EF will not call this method directly
if (b1 == null && b2 == null)
return 0;
else if (b1 == null)
return -1;
else if (b2 == null)
return 1;
return ((IStructuralComparable) b1).CompareTo(b2, Comparer<byte>.Default);
}
}
Run Code Online (Sandbox Code Playgroud)
并在EF LINQ查询中使用它:
var result = ctx.TestTables.Where(c => c.RowVersion.Compare(rv1) > 0).ToList();
Run Code Online (Sandbox Code Playgroud)
在分析时,EF将看到具有名称Compare和兼容签名的方法,并将其转换为正确的sql查询(从表中选择*,其中RowVersion> @yourVersion)