完全に機能する回避策を見つけました!Entity Framework 6.1.3 でテスト済み。
<C# の型システムでは (本来あるべきように) それができないため、バイト配列で演算子を使用する方法はありません。しかし、できることは、式を使用してまったく同じ構文を作成することであり、これを実行できる抜け穴があります。
最初の一歩
完全な説明が必要ない場合は、ソリューション セクションにスキップできます。
式に慣れていない場合は、MSDN の速習コースをご覧ください。
基本的に、入力queryable.Where(obj => obj.Id == 1)すると、コンパイラは入力した場合と同じものを実際に出力します。
var objParam = Expression.Parameter(typeof(ObjType));
queryable.Where(Expression.Lambda<Func<ObjType, bool>>(
Expression.Equal(
Expression.Property(objParam, "Id"),
Expression.Constant(1)),
objParam))
その式は、データベース プロバイダーが解析してクエリを作成するものです。これは明らかに元のものよりもはるかに冗長ですが、リフレクションを行うときと同じようにメタプログラミングを行うこともできます。冗長性は、この方法の唯一の欠点です。生のSQLを書かなければならない、パラメータを使用できないなど、ここでの他の回答よりも良い欠点です。
私の場合、私はすでに式を使用していましたが、あなたの場合、最初のステップは式を使用してクエリを書き直すことです。
Foo lastFoo = GetSomeFoo();
var fooParam = Expression.Parameter(typeof(Foo));
var recent = MyContext.Foos.Where(Expression.Lambda<Func<Foo, bool>>(
Expression.LessThan(
Expression.Property(fooParam, nameof(Foo.Version)),
Expression.Constant(lastFoo.Version)),
fooParam));
<これは、byte[]オブジェクトに対して使用しようとした場合に発生するコンパイラ エラーを回避する方法です。コンパイラ エラーの代わりに、実行時Expression.LessThanに検索を試みてbyte[].op_LessThan失敗するため、実行時例外が発生します。ここで抜け穴の出番です。
抜け穴
その実行時エラーを取り除くために、存在しないデフォルトのメソッド ( ) をExpression.LessThan見つけようとしないように、使用するメソッドを指定します。byte[].op_LessThan
var recent = MyContext.Foos.Where(Expression.Lambda<Func<Foo, bool>>(
Expression.LessThan(
Expression.Property(fooParam, nameof(Foo.Version)),
Expression.Constant(lastFoo.Version),
false,
someMethodThatWeWrote), // So that Expression.LessThan doesn't try to find the non-existent default operator method
fooParam));
すごい!これで必要なのは、実行時に型が他の式と一致するようにMethodInfo someMethodThatWeWrote、署名付きの静的メソッドから作成されることだけです。bool (byte[], byte[])
解決
小さなDbFunctionExpressions.csが必要です。切り捨てられたバージョンは次のとおりです。
public static class DbFunctionExpressions
{
private static readonly MethodInfo BinaryDummyMethodInfo = typeof(DbFunctionExpressions).GetMethod(nameof(BinaryDummyMethod), BindingFlags.Static | BindingFlags.NonPublic);
private static bool BinaryDummyMethod(byte[] left, byte[] right)
{
throw new NotImplementedException();
}
public static Expression BinaryLessThan(Expression left, Expression right)
{
return Expression.LessThan(left, right, false, BinaryDummyMethodInfo);
}
}
使用法
var recent = MyContext.Foos.Where(Expression.Lambda<Func<Foo, bool>>(
DbFunctionExpressions.BinaryLessThan(
Expression.Property(fooParam, nameof(Foo.Version)),
Expression.Constant(lastFoo.Version)),
fooParam));
ノート
Entity Framework Core 1.0.0 では動作しませんが、とにかく式を必要とせずに完全にサポートするために問題を開きました。(EF Core は、 andパラメーターを使用してLessThan式をコピーする段階を通過するため、機能しませんが、抜け穴に使用するパラメーターはコピーしません)。leftrightMethodInfo