2017-10-25 3 views
0

私の "UserAccount"エンティティ/クラスの "Username"プロパティにUNIQUE制約を追加しようとしています。コードファーストでは問題ありませんが、モデルファーストでは、これを達成する方法を見つけることができません。 デザイナーはこの機能をサポートしていません。エンティティクラスは自動生成されるため、アノテーションは使用できません。 OnModelCreating()メソッドがモデルファーストで呼び出されていないため、DbModelBuilderインスタンスがないため、Fluent APIを使用できません。 私が考えることができるのは、UNIQUE制約を作成するアプリケーションの開始時に何らかの手動SQL文を実行することだけです。これはEFの目的を無効にします。 は、ここに私の現在のDbContextクラスである:Entity Frameworkモデルfirst:プログラムでUNIQUE制約を作成します。

public partial class UserAccountsModelContainer : DbContext 
{ 
    public UserAccountsModelContainer() 
     : base("name=UserAccountsModelContainer") 
    { 

    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     throw new UnintentionalCodeFirstException(); 
    } 

    public virtual DbSet<UserAccount> UserAccounts { get; set; } 
} 

私もそれが自動生成されますので、UserAccountのクラスを投稿する気にしないだろうと私はDbContextも自動生成であることを知っている(変更すべきではありませんそれを変更することは可能です)。 これについての助けに感謝します!

+1

モデルは最初にコードの方が先に死んでいます。あなたが本当に運が良ければ、誰かが多かれ少なかれ実用的な解決策を求めて来るでしょうが、あなたのプロジェクトのために最初にモデルから離れる可能性があるかどうかを強く考えてください。 – grek40

+0

既にそれで始まっています;) 私はちょうどそのような単純な仕事がモデルファーストで統合されたとは信じられません。 – Cleo

答えて

0

まず、Entity Framework Code Firstに切り替えることをお勧めします。これは、EFで可能なすべてのことについて、より多くのコントロールを提供します。

これまで私はそれを使用していませんでしたが、私はModel Conventionsを知っています。これらはモデル構成に適用されます。おそらく、一意の制約として設定する必要のある、定義されたモデルタイプ/プロパティのための規約を設定するアプローチになるでしょう。

以下に基づいて、データベースの作成時に最初にモデルの設定を変更する必要があります。

モデル規約は、基本となるモデルのメタデータに基づいています。そこには がCSDLとSSDLの両方の規則です。 CSDL規則から IConceptualModelConventionを実装し、 SSDL規則のIStoreModelConventionを実装するクラスを作成します。

出典:http://www.entityframeworktutorial.net/entityframework6/custom-conventions-codefirst.aspx

モデル規則、概念(C-スペース)と ストア(S-スペース)の2種類があります。この区別は、パイプライン内のどこで の規則が実行されるかを示します。 Cスペースの規則は、アプリケーションが構築するモデル に適用されますが、S-Spaceの規則はモデルのバージョンに が適用されます。

出典:https://entityframework.codeplex.com/wikipage?title=Custom%20Conventions

いくつかのより多くの実装例税込。説明はmsdnのfindabeです。私は彼らがあなたの場合に非常に役立つと思います。 MSDNから

一例:

public class DiscriminatorRenamingConvention : IStoreModelConvention<EdmProperty> 
{ 
    public void Apply(EdmProperty property, DbModel model) 
    {    
     if (property.Name == "Discriminator") 
     { 
      property.Name = "EntityType"; 
     } 
    } 
} 

それはEntityTypeに列弁別の名前を変更します。非常に単純な例ですが、あなたの問題を解決するためにそれを修正することができます:

public class ModelBasedConvention : IConceptualModelConvention<EdmProperty> 
{ 
    public void Apply(EdmProperty property, DbModel model) 
    { 
     if (property.Name == "Username" 
      && property.DeclaringType.GetType() == typeof(UserAccount)) 
     { 
      property.AddAnnotation("UniqueKey", property); 
     } 
    } 
} 
+0

詳細な回答ありがとうございます。このような簡単な作業を行うことの複雑さに照らして、grek40の回答と私自身のテストに基づいて、コードを先に進めることにしました。 – Cleo

関連する問題