私はその場限りの報告システムを持っています。クエリのソースタイプや必須フィールドについて、コンパイル時の知識がありません。 System.Linq.Expressions.Expression
ファクトリメソッドを使用して実行時に式ツリーを記述し、リフレクションを使用してLINQメソッドを呼び出すこともできますが、動的LINQの方が簡単なソリューションです。
レポートシステムは、LEFT JOINの結果を返すクエリを許可します。結合されたテーブルには、データベースのNOT NULL
であるフィールドがあります。ただし、これはLEFT JOIN
であるため、これらのフィールドには特定のレコードのNULL
が含まれます。 EF6で生成された式はこれに該当します。これは、式がnull可能ではない値の型に投影されるためです。
コンパイル時のLINQでこれを行っている場合は、null許容型に明示的にキャストします。
enum Color { Red, Green, Blue }
// using System;
// using static System.Linq.Enumerable;
// using System.Linq;
var range = Range(0, 3).Select(x => (Color)x).AsQueryable();
var qry = range.Select(x => (Color?)x);
動的LINQは明示的な変換をサポートしています。
// using static System.Linq.Dynamic.Core
var qry1 = range.Select("int?(it)");
ただし、クエリで参照できるのは 特定のタイプのセット のみです。クエリでColor
を使用しようとすると、次のようになります。
var qry2 = range.Select("Color(it)");
次のエラーが発生します。
タイプ 'Color'に該当するメソッド 'Color'がありません
明示的にColor?
にキャストしようとした場合:
var qry3 = range.Select("Color?(it)");
私は得ます:
要求された値「色」が見つかりませんでした。
動的LINQライブラリを使用してこれを行うにはどうすればよいですか?
次のスニペットを使用して、入力番号が列挙型の一部であるかどうかを識別できることをお勧めします。
public static bool IsValuePresent<T>(int number) where T : Enum
{
return !Enum.GetValues(typeof(T)).Cast<int>().Contains(number);
}
以下は、入力値が列挙に存在するかどうかを確認するための呼び出しである可能性があります
EnumerationConverter.IsValuePresent<Color>(99); //returns False
EnumerationConverter.IsValuePresent<Color>(2); //returns True
上記のステートメントでFalseが取得されたら、値をnullに設定するか、以下のコードのように整数から列挙型への単純なジェネリック型コンバーターを実行できます。
public static T GetAsEnum<T>(int number) where T : Enum
{
if (Enum.IsDefined(typeof(T), number))
{
return (T)Enum.ToObject(typeof(T), number);
}
return default(T);
}
有効な列挙値を確認してから変換する必要があるという理解に基づいて、上記の解決策を試すことができます。他の側面がある場合は、ここに投稿して更新してください。