Linq-to-Sql:メタデータからヌル可能フィールドを見つけます(または小さなバグに関するストーリー)

これがLinq-to-Sqlです。 どのフィールドがnull値を持つことができ、どのフィールドがnull値を持たないかを見つけるタスクに直面しています-この問題を解決することは、例えば、フォーム上の必要なフィールドを強調表示するのに役立ちます、または単にオブジェクトのプロパティに設定する前にデータを検証します。

ステップ1-次の形式の単純なテーブルを作成します。



ステップ2-プロジェクトを作成します(たとえば、コンソールアプリケーションで十分です)。 Model Linq-To-Sqlを追加します。これに、LinqBugTableテーブルにマッピングを追加します。価格のNullableプロパティがFalseに設定されていることに注意してください。



不動産価格のコードはまだ表示しませんが、番号については表示します。
[Column(Storage= "_number" , DbType= "VarChar(50) NOT NULL" , CanBeNull= false )]

public string number

{ get { .... } set { .... } }




* This source code was highlighted with Source Code Highlighter .




このことから、このプロパティのColumnAttributeから、フィールドに空の値を設定できることがわかります。 LinqBugTableの部分クラスを作成し、そのプロパティに関する情報を出力します。

partial class LinqBugTable

{

public void WriteNullableInfo()

{

foreach (PropertyInfo property in GetType().GetProperties())

{

foreach (ColumnAttribute columnAttribute in property.GetCustomAttributes( typeof (ColumnAttribute), true ))

{

Console .WriteLine( "Property: '{0}', CanBeNull: '{1}'" , property.Name, columnAttribute.CanBeNull);

}

}

}

}




* This source code was highlighted with Source Code Highlighter .




すべて準備ができているようですが、結果は次のようになります。



プロパティ: 'id'、CanBeNull: 'True'

プロパティ: 'price'、CanBeNull: 'True'

プロパティ: 'number'、CanBeNull: 'False'



idとpriceでわかるように、Trueは返されますが、もちろんそうではありません。 ここで、クラスの価格プロパティの説明を見てみましょう。

[Column(Storage= "_price" , DbType= "Money NOT NULL" )]

public decimal price

{ get { .... } set { .... } }




* This source code was highlighted with Source Code Highlighter .




Column属性からわかるように、CanBeNullプロパティは設定されていませんが、一般に、bool変数はfalseに設定されているため、恐らくはないでしょう(最初は思っていたように)。 ColumnAttributeコードで何が起こっているのかを確認できるすばらしいReflectorプログラムがあると便利です。



コンストラクターで、フィールドをtrueに初期化することがわかります。 一般に、ColumnAttributeにはCanBeNullSetプロパティもあります。これは残念ながら内部であり、プロパティが設定されているかどうかを調べることができます。

反映して、ロジックを理解しました:価格プロパティは、単にnullにできない小数型を返し、このフィールドのモデルデザイナでNullable = Trueプロパティを設定すると、Nullable <decimal>型になります。 一般に、ValueType型(構造)のフィールドでは、Linq-To-SqlはCanBeNullに関連付けられた説明を生成しません。 結論として、メソッドを少し書き換えます。

public void WriteNullableInfo()

{

foreach (PropertyInfo property in GetType().GetProperties())

{

foreach (ColumnAttribute columnAttribute in property.GetCustomAttributes( typeof (ColumnAttribute), true ))

{

bool canBeNull = (Nullable.GetUnderlyingType(property.PropertyType) != null )

|| (columnAttribute.CanBeNull && !property.PropertyType.IsValueType);

Console .WriteLine( "Property: '{0}', CanBeNull: '{1}'" , property.Name, canBeNull);

}

}

}




* This source code was highlighted with Source Code Highlighter .




ここで、プロパティがNullable <T>型である場合、Trueを返すことを確認します。そうでない場合、フィールド型が構造体ではないことを考慮して、CanBeNullを返します。 さて、プロパティタイプではValueTypeがこのスキームにあった唯一の問題であることを願っています。 ;)




All Articles