使用Entity Framework按时间戳列选择新记录

5

我在我的SQL Server数据库中有一个带有时间戳列(RowId)的表。

我想根据这个时间戳查询新行。 SQL查询如下:

SELECT *
 FROM [MyTable]
 where RowId>=0x0000000000A99B06

0x0000000000A99B06 是上一个查询的最大时间戳值。

如何在使用Entity Framework数据库优先的情况下进行此类查询?RowId 映射到 byte[] 属性,我不知道如何在LINQ查询中比较字节数组。

3个回答

17

实际上,你可以进行一些小的技巧。这对我有百分之百的效果。

internal static class EntityFrameworkHelper
{
   public static int Compare(this byte[] b1, byte[] b2)
   {
      throw new NotImplementedException();
   }  
}

然后你就可以像这样使用它:

public void SomeMethod()
{
   var messages = Set<Message>().Where(m => m.Modified.Compare(filter.TimeStamp) > 0).ToList();
}
它最终会生成类似这样的SQL语法:"Select * from Messages Where Modified > @param"。它是有效的,也不会抛出异常。

这是解决此问题的绝佳方案。如果有人需要,还有另一种更复杂的解决方案,可以创建此问题的通用版本:https://dev59.com/Qms05IYBdhLWcg3wG-VR#38152016 - Lukas K
我们的代码库中也有这个同样的 hack。我不知道为什么 EF 不能直接做正确的事情。 - Nelson

1
另一种方法是使用EntityFramework的普通SQL语句。这可以避免额外的内部查询(请参见Gert Arnold的回答和我的评论),但看起来很丑陋。
long timeStamp = 100500;
IEnumerable<MyTable> result = context.Database.SqlQuery<MyTable>(String.Format("SELECT * FROM MyTable WHERE ROWID>{0} ORDER BY RowId ASC", timeStamp));

1
由于Entity Framework不允许在时间戳比较中使用">="运算符,因此您无法使用它来实现此操作。它仅允许使用"="运算符。您可以尝试使用以下方法:
var b = BitConverter.GetBytes(1000000L);
var query = from x in MyTable
            where x.RowId = b; // not >=

但那样并不是很有用。所以你需要找到另一种方式来获取新行,例如使用自增列的值,或添加一个“真正”的时间戳(datetime)列。


一般来说,我可以按照以下方式完成:(从MyTable中选择x 其中x.Id > (从MyTable中选择k 其中k.ROWID == b 选择k.Id)。第一个() 选择x);谢谢。 - Sir Hally

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接