1

私のすべてのエンティティはIValidatableObjectから継承しています。私が抱えている問題は、エンティティを保存していて、これに完全にロードされていない別のエンティティを参照するプロパティが含まれている場合 (null ではなく、内部に参照キーを持つオブジェクトのみが含まれている)、コードでエラーが発生することです。エラーは、(別のエンティティを参照する) プロパティが正しく検証されていないことです。これは、オブジェクトに ID のみが含まれているためです。小さな例を挙げて、私が話していることをお見せしましょう。

public class Exercise : BaseModel
{
    public LocalizedString Name { get; set; }
    public virtual Muscle Muscle { get; set; }

    public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Name == null)
        {
            yield return new ValidationResult("Name is mandatory", new[] { "Name" });
            yield break;
        }

        if (Name.French == null || Name.French.Length < 3)
        {
            yield return new ValidationResult("Exercise's French name must be over 3 characters");
        }

        if (Name.English == null || Name.English.Length < 3)
        {
            yield return new ValidationResult("Exercise's English name must be over 3 characters");
        }

        if (Muscle == null)
        {
            yield return new ValidationResult("Exercice must be assigned to a muscle");
        }
    }
}

public class Muscle : BaseModel
{
    public LocalizedString Name { get; set; }
    public ICollection<Exercise> Exercises { get; set; }
    public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Name == null)
        {
            yield return new ValidationResult("Name is mandatory", new[] { "Name" });
            yield break;
        }

        if (Name.French == null || Name.French.Length < 3)
        {
            yield return new ValidationResult("Muscle's French name must be over 3 characters");
        }

        if (Name.English == null || Name.English.Length < 3)
        {
            yield return new ValidationResult("Muscle's English name must be over 3 characters");
        }
    }
}

//--- This is the code into the repository:
public int Insert(Exercise entity)
{
    if (entity.Muscle != null)
    {
        var localExercise = DatabaseContext.Set<Muscle>().Local.SingleOrDefault(e => e.Id == entity.Muscle.Id);
        if (localExercise != null)
        {
            DatabaseContext.Set<Muscle>().Attach(entity.Muscle);
        }
    }

    DatabaseContext.Set<Exercise>().Add(entity);
    return DatabaseContext.SaveChanges();
}

演習を保存しています。エクササイズには名前が含まれており、マッスルには有効な ID が設定されていますが、名前は含まれていません。このため、保存時に Entity Framework 内で検証が行われ、Muscle オブジェクトには名前が必要であることがわかりました。

これをアタッチしたいだけなので、Muscle を完全にロードする必要はありません。エクササイズ内にプロパティ「MuscleID」を入れたくありません。どうしてもこの構造にしたい。

外部オブジェクトではなく、保存されたエンティティでのみ検証を行うために何をする必要があるか教えてもらえますか?

4

1 に答える 1

0

コントローラーとビューの間で ViewModel を使用する必要があります。そうすれば、モデルを方程式から遠ざけることができます。AutoMapperを使用して、コントローラーのポストバック時に ViewModel プロパティをモデルにマップします。ViewModel は、検証規則を定義し、IValidatableObject を実装できます。すべての ViewModels を基になるエンティティを持たないように定義することもできます。これにより、余分なエンティティとプロパティが表示されなくなります。if (ModelState.IsValid) チェックの後、AutoMapper を使用して ViewModel をモデルにマップしてください。

于 2013-02-06T03:39:39.130 に答える