0

ASP.NET MVC 4 Web アプリを作成しています。DbContext.ValidateEntity追加しようとしているエンティティがいくつかのチェックに合格するかどうかを確認するために使用しています。Nameカスタムプロパティが一意であるかどうか、または他のプロパティがカスタム ロジックを通過するかどうかなどを確認します。

ただし、単体テストで、予期しない動作が検出されました。私はリポジトリ パターンをDbContext使用しており、データベースから EF モデル エンティティを取得するために使用してリポジトリ関数に渡すグローバルがあります。

前もって、問題は、 の内部でValidateEntity、追加されるエンティティを確認するときに、既存のすべてのエンティティを照会し、特定のフィールドがいくつかの一意性チェックに合格することを確認することです。しかし、クエリを実行した既存のアイテムでは、既にアイテムが追加されていることがわかります。

たとえば、データベースにエンティティが存在せず、最初のエンティティを作成しているValidateEntity場合、既存のすべてのエンティティに対してクエリを実行すると、エンティティが表示されます。

データベースに送信する前に、コレクション内のすべてのエンティティが必要だSaveChangesと思いましたか?ValidateEntity

4

3 に答える 3

1

データベースで「一意性をチェック」する必要はありません。データベースは、すでにそれを行うように設計されています。データベースには、適用できる一意の制約と呼ばれるものがあり、挿入がそれらの制約に違反すると、例外がスローされます。必要なのは、その例外をキャッチして処理することだけです。データベースが行うことを行うために一連のコードを追加することは、冗長で遅く、さらにはエラーが発生しやすいことは言うまでもありません。

于 2013-10-09T05:39:29.273 に答える
0

ValidateEntity を使用する代わりに、カスタム検証属性を使用できますか? 値が decimal かどうかをチェックするカスタム属性の例を次に示します。

public class MustBeDecimalAttribute : ValidationAttribute, IClientValidatable
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (Equals(value, null))
                return ValidationResult.Success;

            using (new CultureSubstitution(CultureInfo.InvariantCulture))
            {
                if (string.IsNullOrWhiteSpace(value.ToString()))
                    return ValidationResult.Success;

                return !value.ToString().ToDecimal().HasValue
                           ? new ValidationResult(FormatErrorMessage(validationContext.DisplayName))
                           : ValidationResult.Success;
            }
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
                           {
                               ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
                               ValidationType = "mustbedecimal"
                           };

            yield return rule;
        }

ただし、データベースにクエリを実行する必要があるため、IClientValidatable を実装しないでください。属性を作成したら、次のようにモデルに追加します。

[MustBeDecimal]
public decimal? RegularPrice { get; set; }
于 2013-10-09T01:13:27.293 に答える