1

私はEF5をコードファーストで流暢なマッピングアプローチで使用しています。これが私のシナリオです。わかりやすくするために切り詰めています。

public class SecuritySettings
{
   public int Id { set; set }
   public Company Company { get; set; }
   public int MaximumInvalidPasswordAttempts { get; set;
   // etc.
}

public class Company
{
   public int Id { set; set }
   public string Name { get; set; }
   public SecuritySettings InternalUserSecuritySettings { get; set; }
   public SecuritySettings ExternalUserSecuritySettings { get; set; }
}

上記だけで、Companyテーブルに2つのFKが表示されます。

   InternalUserSecuritySettings_Id int, null
   ExternalUserSecuritySettings_Id int, null

ここまでは順調ですね。

流暢なマッピングを設定するために使用した構成クラスがあります。1つはCompany用、もう1つはSecuritySettings用です。これらは必要なプロパティを規定しています。会社の構成内で、次のことを行うと、次のようになります。

HasRequired(x => x.InternalUserSecurityConfiguration);

これにより、次のようになります。

InternalUserSecuritySettings_Id int、nullではないExternalUserSecuritySettings_Id int、null

しかし、私がこれを追加すると:

HasRequired(x => x.ExternalUserSecurityConfiguration);

次の例外が発生します。

テーブル「Companies」にFOREIGNKEY制約「FK_dbo.Companies_dbo.SecuritySettings_ExternalUserSecurityConfiguration_Id」を導入すると、サイクルまたは複数のカスケードパスが発生する可能性があります。ON DELETENOACTIONまたはONUPDATENO ACTIONを指定するか、他のFOREIGNKEY制約を変更します。

私が試してみました:

  1. .WithRequiredDependent(y => y.Company).WillCascadeOnDelete(false)
  2. .WithRequiredDependent(y => y.Company).Map(m => m.MapKey( "ExternalUSC_Id"))

他のそのような順列の中で、例外が発生するか、FKの1つだけが作成されます。これは、エンティティ構成の流暢なマッピング(できれば会社のもの)内で行いたいと思います。明らかな何かが欠けていますか?null以外の非常に簡単で些細なことから、単純に規定するのが非常に難しいものに移行するのは非常に残念なことのようです。それぞれにキーが必要であり、両方ともnullであってはなりません。

実際の外部キーに別のプロパティを使用してこれを機能させる方法を見つけましたが、最初に、これはnull以外の要件に対して非常に余分な労力のようであり、次に、OnModelCreatingメソッドで多くの構成を宣言する必要がありました。 「WithMany()」マッピングは、私には直感に反します。

4

2 に答える 2

0

次の流暢さを使用することで、これをnull以外のプロパティで機能させることができます。

        modelBuilder.Entity<Company>().
            HasRequired(x => x.InternalUserSecuritySettings)
            .WithMany()
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Company>().
            HasRequired(x => x.ExternalUserSecuritySettings)
           .WithMany()
            .WillCascadeOnDelete(false);

このデータベースを作成します。

ここに画像の説明を入力してください

しかし-私はあなたのエンティティのCompanyプロパティについて少し心配しています。SecuritySettingsそのnavプロパティをInternal/ExternalSecuritySettingsプロパティの反対側にマップしますか?その場合、これはEFでは実行できません(1つのエンティティに1つのプロパティを設定することはできず、他の2つのプロパティにマップすることはできません)。理由を検討するには: -Companyにaを追加した場合SecuritySetting

var CompanyA = new Company;
CompanyA.SecuritySettings(new SecuritySettings());

エンティティのどちらの端にSecuritySettingsマップする必要がありますか(内部または外部?)上記のシナリオでは無効であると判断できないためです。

会社に2つの異なるコレクションを追加するSecuritySettingsと、適切なマッピングが得られます。

于 2013-03-01T12:39:33.060 に答える
0

RE: Mark Oreta - ソース管理の履歴を見ると、会社のプロパティはもともとそこにはありませんでした。会社のコンテキスト内でこれを行わずにセキュリティ設定を参照する必要がないため、これを削除しました。私はあなたのものと同様のバージョンを持っていましたが、あなたの答えから、少なくとも OnModelCreating メソッドではなく、CompanyConfiguration クラス内にすべてのマッピングを追加できるように導くことができたので、あなたのものを答えとして取りました. 現在の唯一の問題点は、これらがまだ 1 対 1 のマッピングであることを意図しており、WithMany() が推論または強制しないことです。したがって、これを強制できる唯一の方法は、一意の制約を使用することです。あまりきれいではありません!お時間をいただき、ご回答いただきありがとうございます。

編集:

この問題に対する私の現在のバージョンの回答を共有するために:

  1. 会社の構成クラス (DataEntityBaseConfiguration は EntityTypeConfiguration から継承されます)
public class CompanyConfiguration : DataEntityBaseConfiguration<Company>
   {
    public CompanyConfiguration()
    {
        Property(x => x.Name).IsRequired();
        Property(x => x.Name).HasMaxLength(256);
        HasRequired(x => x.InternalUserSecurityConfiguration).WithMany().WillCascadeOnDelete(false);
        HasRequired(x => x.ExternalUserSecurityConfiguration).WithMany().WillCascadeOnDelete(false);

    }
   }

次に、Context Initializer クラスに次のコード行を追加して、両方のプロパティに一意の制約を適用します。

AddUniqueConstraint<Company>(() => new Company().ExternalUserSecurityConfigurationId);
AddUniqueConstraint<Company>(() => new Company().InternalUserSecurityConfigurationId);

AddUniqueConstraint は、一意の制約を作成するための SQL を実行するために私が作成したメソッドです。詳細については、こちらを参照してください。

于 2013-03-01T13:15:01.717 に答える