23

ASP.NET MVC 4、EF5、コード ファースト、SQL Server 2012 Express

モデルに一意の値を適用するためのベスト プラクティスは何ですか? すべての場所で一意である必要がある「url」プロパティを持つ場所クラスがあります。

public class Place
{
      [ScaffoldColumn(false)]
      public virtual int PlaceID { get; set; }

      [DisplayName("Date Added")]
      public virtual DateTime DateAdded { get; set; }

      [Required(ErrorMessage = "Place Name is required")]
      [StringLength(100)]
      public virtual string Name { get; set; }

      public virtual string URL { get; set; }
};

配置できる[固有の]データ注釈だけがないのはなぜですか?

これに関する議論を 1 つか 2 つ見たことがありますが、ベスト プラクティスについての話はありません。Code First を使用して、データベース内のフィールドに一意の制約を設定するようにデータベースに指示できますか?

最も簡単な方法とベストプラクティスは何ですか?

4

7 に答える 7

5

唯一の方法は、移行を使用していると仮定して、生成後に移行を更新し、列に一意の制約を適用することです。

public override void Up() {
  // create table
  CreateTable("dbo.MyTable", ...;
  Sql("ALTER TABLE MyTable ADD CONSTRAINT U_MyUniqueColumn UNIQUE(MyUniqueColumn)");
}
public override void Down() {
  Sql("ALTER TABLE MyTable DROP CONSTRAINT U_MyUniqueColumn");
}

ただし、難しいのは、データベースに到達する前にコード レベルで制約を適用することです。そのためには、一意の値の完全なリストを含むリポジトリが必要になる場合があり、ファクトリ メソッドによって新しいエンティティがそれに違反しないようにします。

// Repository for illustration only
public class Repo {
  SortedList<string, Entity1> uniqueKey1 = ...; // assuming a unique string column 
  public Entity1 NewEntity1(string keyValue) {
    if (uniqueKey1.ContainsKey(keyValue) throw new ArgumentException ... ;
    return new Entity1 { MyUniqueKeyValue = keyValue };
  }
}

参考文献:

脚注:

最初にコードで [Unique] を求めるリクエストが多数ありますが、バージョン 6 も作成していないようです: http://entityframework.codeplex.com/wikipage?title=Roadmap

ここで投票してみてください: http://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/1050579-unique-constraint-ie-candidate-key-support

于 2013-05-21T20:16:53.133 に答える
3

データをデータベース テーブルに保存する前に、コード レベルでこのチェックを行うことができます。

ビューモデルでデータ注釈を使用しRemoteて非同期検証を実行し、UI の応答性を高めることができます。

public class CreatePlaceVM
{
  [Required]
  public string PlaceName { set;get;}

  [Required]
  [Remote("IsExist", "Place", ErrorMessage = "URL exist!")
  public virtual string URL { get; set; }
}

パラメーターを受け入れるIsExistsアクション メソッドがあることを確認し、それをテーブルに対してチェックして、true または false を返します。PlacecontrollerURL

このmsdn リンクには、リモート属性を実装して即時検証を行う方法を示すサンプル プログラムがあります。

また、ストアド プロシージャを使用している場合 (何らかの理由で)、クエリEXISTSの前にチェックを行うことができます。INSERT

于 2013-05-21T20:24:40.913 に答える
2

検証フローでコンストラクター注入を有効にするという一般的な問題を解決し、この回答のフレームワークに頼らずに通常の DataAnnotations メカニズムに統合し、次のように記述できるようにしました。

class MyModel 
{
    ...
    [Required, StringLength(42)]
    [ValidatorService(typeof(MyDiDependentValidator), ErrorMessage = "It's simply unacceptable")]
    public string MyProperty { get; set; }
    ....
}

public class MyDiDependentValidator : Validator<MyModel>
{
    readonly IUnitOfWork _iLoveWrappingStuff;

    public MyDiDependentValidator(IUnitOfWork iLoveWrappingStuff)
    {
        _iLoveWrappingStuff = iLoveWrappingStuff;
    }

    protected override bool IsValid(MyModel instance, object value)
    {
        var attempted = (string)value;
        return _iLoveWrappingStuff.SaysCanHazCheez(instance, attempted);
    }
}

いくつかのヘルパー クラス (あちらを見てください) を使用して、たとえば ASP.NET MVC で次のように接続しますGlobal.asax:-

DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(
    typeof(ValidatorServiceAttribute),
    (metadata, context, attribute) =>
        new DataAnnotationsModelValidatorEx(metadata, context, attribute, true));
于 2016-02-05T10:17:53.107 に答える