2

既存のレガシー データベースで EF Database First を使用しています。データベースではほとんどすべてのフィールドに maxlength 値があり、この値は .edmx ファイルで確認できます。

たとえば、フィールドのCCSTATUSnvarchar(20)です。ユーザーが 20 文字を超える文字を入力すると、 はクリアされますが、 onModelState.IsValidがスローされます。DbEntityValidationExceptiondb.SaveChanges()

DataAnnotations を追加したプロパティの場合、検証に失敗すると、モデル エラーが追加され、ユーザーに表示されて修正できるようになります。Model MetaData クラスのすべてのプロパティに属性を追加できることは承知していますが、値がプロパティの最大長よりも大きい場合[MaxLength(n)]にスローする代わりに、EF にモデル エラーを追加させる方法はありますか?DbEntityValidationException

編集

回答ありがとうございます。最終的に、EF Power Toolsのリバース エンジニアリング Code First 機能を使用して、データベースから Code First モデルを生成しました。これには、適切な maxlength 属性とその他の必要な注釈が含まれていました。

4

3 に答える 3

3

The reason of this behavior is that EF and ASP.NET MVC are two different things. The ModelState is a concept of MVC and it has nothing to do with EF edmx metadata. If you want to use the same class to represent action input and a domain entity then you should go with the [MaxLength(n)] attribute solution. However, I would recommend to use a viewmodel/dto instead.

I wouldn't go with the solution of @Reinard (catching the DbEntityValidationException) for the following reasons: you are validating input and you are checking the result of the input validation inside the controller action. DbEntityValidationException indicates a problem at a completely different layer (database). This kind of layer mixing will hurt you sooner or later. Another reason is that you shouldn't use exceptions like this, but this is a different topic, e.g.: Why not use exceptions as regular flow of control?

于 2013-07-29T15:51:27.650 に答える
0

DbEntityValidationException をキャッチしてモデル状態エラーを追加してみませんか? これにより、ModelState.IsValid が false に設定されます。

    try
    {
      repo.Save(model);
    }
    catch (DbEntityValidationException ex)
    {
      ModelState.AddModelError("EntityError", ex);
    }

これを拡張して、エラーの原因となったフィールドをログに記録するユーティリティ メソッドを作成できます。

foreach (var validationErrors in ex.EntityValidationErrors)
{
    foreach (var validationError in validationErrors.ValidationErrors)
    {
        string error = string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
    }
}

編集: Peter Porfy の回答によると、通常の制御フローの一部として例外を使用しないようにする必要があることに同意します。[MaxLength(n)] 属性を使用するのが理想的であり、T4 テンプレートを変更して、poco を生成するときにデータベースからこれを取得することができます。そうは言っても、レガシーデータベースと統合していることを考えると、スキーマの変更は「新しい」アプリケーション(開発中のものなど)の範囲外で発生する可能性があると思います。つまり、これらのような例外がより一般的になる可能性があります。その場合、私が提供した上記のコード サンプルが役立つ場合があります。また、スキーマが変更されるたびにコードを変更する必要があるのか​​、それとも事前に (ある程度) 対応する必要があるのか​​は、まったく別の議論だと思います。

于 2013-07-29T15:26:07.023 に答える
0

あなたが望むのは、T4 テンプレートを変更して DataAnnotation を自動的に追加することだと思います。

于 2013-07-29T19:00:43.560 に答える