ドメインモデルを介してCLRにマップしたリレーショナルデータベースにカスタムエンティティがあります。そのため、次のステートメントを使用することで、ドメインモデルでのLINQクエリを介して、データベースからメモリにエンティティを取り込むことができます。
var inspection = (from i in dbContext.New_testinspectionExtensionBases
where i.New_testinspectionId == currentInspection
select i).First();
このエンティティには、アクセスする必要のあるプロパティ/フィールドがあります。プロパティ/フィールド名とその値を決定できる必要があります。メモリ内のこれらのアイテムをループし、それらの名前と値をコンソールに書き出したいと思います。
私はこのアプローチを使用しようとしましたが、構文を修正する方法を理解できませんでした(または、GetPropertiesが使用する正しいメソッドであると確信しています。しかし、私が必要とするのは値への読み取りアクセスだけなので、それは本当に重要ではありません。
var inspectionReportFields = inspection.GetType().GetProperties();
// I called this inspectionReportfields because the entity properties correspond to
// form/report fields I'm generating from this data.
foreach (var reportField in inspectionReportFields)
{
var value = reportField.GetValue();
Console.WriteLine(reportField.Name);
Console.WriteLine(value);
}
EFやopenaccessのようなドメインモデルを利用する場合、プロパティ/フィールド値を取得する簡単な方法はありますか?そうでない場合、私はそれを正しい方法で行っていますか?そして最後に、もしそうなら、どのようにして値変数宣言の構文を修正しますか?
参照用に、ドメインモデルによって生成されたコードからのサンプルフィールド/プロパティを次に示します。
private int? _new_systemGauges;
public virtual int? New_systemGauges
{
get
{
return this._new_systemGauges;
}
set
{
this._new_systemGauges = value;
}
}
private int? _new_systemAlarm ;
public virtual int? New_systemAlarm
{
get
{
return this._new_systemAlarm;
}
set
{
this._new_systemAlarm = value;
}
}
オブジェクトの構造について何も知らずにオブジェクトを「ダンプ」する汎用的な方法を定義しようとしていると思います。もしそうなら、あなたは物事を正しい方法で進めています。リフレクション(GetType()
および関連するType
クラスメソッド)を使用して、オブジェクトを検査し、その情報を返します。
GetFields()
が何も返さなかった理由は、おそらく正しいバインディングフラグを提供しなかったからです。特に、パラメーターを取らないオーバーロードを呼び出すと、public
フィールドのみが返されます。プライベートフィールドが必要な場合は、具体的に尋ねる必要があります。
あなたの場合、GetFields(BindingFlags.NonPublic)
は__new_systemGauges
_および__new_systemAlarm
_フィールドを返し、GetProperties()は_New_systemAlarm
_および_New_systemAlarm
_プロパティを返します。
見逃したもう1つの重要な要素は、取得するデータがtypeメタデータであることです。特定のインスタンスではなく、class
の構造を定義します。特定のインスタンスのプロパティの値が何かを知りたい場合は、それを要求する必要があります。
_foreach (var prop in obj.GetType().GetProperties())
{
Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(obj, null));
}
_
タイプのメタデータからPropertyInfo
要素の1つを持っている場合、そのタイプの任意のインスタンスでそのプロパティ値を要求できます。最初に使用したインスタンスと同じである必要はありません。例えば:
_var objs = somelist.Where(x => x.Id == 1);
foreach (var prop in objs.First().GetType().GetProperties())
{
int x = 0;
foreach (var obj in objs)
{
if (prop.PropertyType.Name.Equals("Int32"))
{
int val = (int)prop.GetValue(obj, null);
Console.WriteLine("Obj #{0}: {1} = 0x{2:x8}", x++, prop.Name, val);
}
else if (prop.PropertyType.Name.Equals("Decimal"))
{
int val = (decimal)prop.GetValue(obj, null);
Console.WriteLine("Obj #{0}: {1} = {2:c2}", x++, prop.Name, val);
}
else
{
Console.WriteLine("Obj #{0}: {1} = '{2}'", x++, prop.Name, prop.GetValue(obj, null));
}
}
}
_
技術的には、GetIndexParameters
の結果をチェックして、プロパティにインデックスが付けられているかどうかを確認する必要があります。 null
のGetValue
パラメーターは、実際にはインデックス値の配列です。
返される値を変換するには、タイプキャストを使用するか、もう少し柔軟にしたい場合は、Convertクラスのメソッドを使用します。違いは、たとえば、short
プロパティがある場合、GetValue()
はint
として型キャストできないボックス化されたshortを返します。最初にshort
に展開する必要があります。 Convert.ToInt32()
を使用すると、convertible(であるプロパティからint
値を取得するために必要なすべてのステップが実行されます。 )整数。
参照タイプ間の変換は、そのためにis
とas
を使用できるだけなので簡単です。これらは、「反映された」プロパティ値で期待するように機能します。
GetProperties
は確かに正しい方法です。
コンパイラエラーを取り除くには、コードを次のように変更します。
var value = reportField.GetValue(inspection, null);
PropertyInfo
オブジェクトは特定のクラスインスタンスにバインドされていないため、値を取得するインスタンスを渡す必要があります。
標準の.NET命名規則に従うことを検討してください。
これは、次のことにつながります。
New_systemAlarm
の代わりにNewSystemAlarm
newSystemAlarm
または_newSystemAlarm
の代わりに_new_systemAlarm
NewTestInspectionExtensionBases
の代わりにNew_testinspectionExtensionBases
NewTestInspectionId
の代わりにNew_testinspectionId
OpenAccessを使用している場合、モデルクラスに関する完全な情報をいつでも入手できます。マッピングから情報が取得されるため、クラスを反映する必要はありません(オーバーヘッドなし)。
すべてのクラスマッピング情報について、context.Metadata.PersistentTypesを参照するだけです。