1

ボトムラインアップフロント

EntityFrameworkで親に属することができる子エンティティの数を制限できる簡潔な方法はありますか?現在、4.3.1を使用しています。

問題

EntityFrameworkを使用するデータアクセスレイヤーを介してデータにアクセスするASP.NETMVC3サイトを開発しています。Searchエンティティと多対多の関係を持つSearchListエンティティがあります。SearchListには多くの検索が含まれる場合があり、Searchは多くのSearchListに属する場合があります。

サイトのワークフローのある時点で、ユーザーはバッチ検索で使用する検索やその他のアイテムを選択する必要があります。ページに検索リスト全体をロードする必要があります。

SearchListは非常に大きくなる可能性があり、テストとして21,000回の検索で作成しました。数秒かかり、返されるデータは約9.5 MBでした。これは予想どおりでしたが、jQueryUIは、それだけテーブル化しようとすると窒息しました。

私たちが欲しいもの

したがって、検索リストが持つことができる検索の数に制限を課したいと思います。アプリケーションを調べて、コレクションのサイズをチェックし、追加しようとしている検索に現在のサイズを加えたものかどうかをチェックする一連のルールを設定できます... yadayadayada。

ただし、より良い方法(特に、MVCが取得するエラーメッセージを簡単に出力できる方法)があれば、代わりにそれを完全に採用します。

私はグーグルで検索し、多くのEFブログを熟読しましたが無駄になりました。子を制限し、コレクション内の子の最大数および同様の検索で、LinqクエリとCountおよびMaxメソッドに関する結果が返されました。

どんな助けでもいただければ幸いです。

4

2 に答える 2

1

組み込みの方法はないため、このような検証を自分でコーディングする必要があります。いくつかの簡単なアイデア:

  • たとえば、ナビゲーションプロパティにカスタムコレクションを使用すると、しきい値を超える検索を追加しようとしたときに例外が発生します。シンプルですが、すべての検索をロードする必要があり、同時実行の問題が発生し、さらに検索リストとデータベースからの検索のロード中に発生する可能性があります。
  • オーバーライドして処理できますSaveChanges。少なくとも、検索リストにすでに関連している検索の数を確認する必要がありますが、並行性の問題が発生します(他のリクエストが同じリストに検索を追加しようとして、残りの場所が1つしかない場合は、どちらも確認と挿入に成功します関連検索)
  • データベーストリガーで処理できます-これも同時実行の問題があります

同時実行の問題を完全に回避するには、ロックヒントを使用した手書きのクエリが必要です。これにより、1つのリクエストのみが検索リストごとの検索数をチェックし、アトミックトランザクションに新しい検索を挿入できるようになります。

于 2012-06-18T15:59:27.857 に答える
0

私は結局CustomValidationAttributeを使用し、それを実装して大成功を収めました。私の実装情報については、以下を参照してください。

SearchListエンティティ内

    [NotMapped]
    public String ValidationMessage { get; set; }
    [CustomValidation(typeof(EntityValidation.EntityValidators), "ValidateSearchCount")]
    public virtual List<Search> Searches { get; set; }

    public static bool Create(ProjectContext db, SearchList searchList)
    {
        try
        {
            db.SearchLists.Add(searchList);
            db.SaveChanges();
            return true;
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    searchList.ValidationMessage += validationError.ErrorMessage;
                }
            }
            return false;
        }
        catch (Exception)
        {
            return false;
        }
    }

EntityValidatorsクラス

    public static ValidationResult ValidateSearchCount(List<Search> Searches)
    {
        bool isValid;
        int count = Searches.Count();
        isValid = (count <= 5000 ? true : false);

        if (isValid)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult("A maximum of 5000 searches may be added to a SearchList.");
        }
    }

同様の例外ブロックがupdateメソッドにあります。このように、SaveChangesが呼び出されると、エンティティとその子コレクションの検証が試行され、コレクション数が5000を超えると、バリデーターはエラーメッセージを返します。このエラーメッセージは、例外ハンドラーでキャッチされ、ローカルプロパティに格納されます。物事がうまくいかないときにチェックするコントローラー。

于 2012-06-25T20:28:35.117 に答える