Rowversion comparison in Entity Framework
Asked Answered
G

3

12

How should I compare rowversion fields using Entity Framework? I have one table which has a rowversion column, I want to get data from tables for which the row version is higher than specified value.

byte[] rowversion = ... some value;
 _context.Set<T>().Where(item => item.RowVersion > rowVersion);

This line does not work, it throws the error:

Operator '>' cannot be applied to operands of type 'byte[]' and 'byte[]'

Any idea how I can compare rowversion fields in C#/Entity Framework?

Godhead answered 2/10, 2012 at 15:59 Comment(2)
With rowversion column, you can basically only check for equality (or non-equality) - you cannot really test for "larger than" or not.Trickish
@Trickish I thought so too, but actually, taking a closer look, the documentation speaks of rowversion values getting incremented, which supports the observation that a rowversion can be treated as a 64-bit integer, and higher values have been inserted into the database later, and it being a 64-bit integer would mean there is no realistic chance of overflow.Vipul
M
11

Here is what we did to solve this. Use a compare extension like this:

public static class EntityFrameworkHelper
{
    public static int Compare(this byte[] b1, byte[] b2)
    {
        throw new Exception("This method can only be used in EF LINQ Context");
    }
}

Then you can do this:

byte[] rowversion = .....somevalue;
_context.Set<T>().Where(item => item.RowVersion.Compare(rowversion) > 0);

The reason this works without a C# implementation is because the Compare extension method is never actually called, and EF LINQ simplifies x.Compare(y) > 0 down to x > y.

Mf answered 13/3, 2017 at 14:1 Comment(2)
This is truly sage magic and feels like a giant hackWince
Can confirm: Works in .NET 6.0. I'm stunned.Chlori
N
1

Are you sure that is Kosher use of RowVersion ? What happens when it rolls over ?

I think you will need to convert it to string or int first. eg

Encoding.Unicode.GetString(ba)

You can also call SPs from EF. :-)

Nancinancie answered 12/10, 2012 at 15:21 Comment(1)
Even if you could sustain 1 million inserts/updates per second for that one table continuously, it would roll over in about 584 thousand years if my math is right.Scorpius
G
0

Use EntitySQL.

// Drop down to ObjectContext and query against ObjectSet:
var objectContext = (dbContext as IObjectContextAdapter).ObjectContext;
// Create param for EntitySQL
var param = new ObjectParameter("rowVersion", rowVersion);
// Create IQueryable<T>
var query = objectContext.CreateObjectSet<T>.Where("it.RowVersion > @rowVersion",param);
Gavrah answered 15/11, 2013 at 15:29 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.