4

確かに、EF 4.1 RC Codefirst、DataAnnotations、FluentAPIの機能はまだ私には圧倒されています。時々私は自分が何をしているのか本当にわからない;-)次のPOCOを見てください:

public class Country
{
    [Key]
    public Guid ID { get; set; }

    [Required]
    public virtual Currency Currency { get; set; }
}

public class Currency
{
    [Key]
    public Guid ID { get; set; }

    public virtual ICollection<Country> Countries { get; set; }
}

一般的な考え方:すべての国が通貨を持っている必要があります。ただし、通貨を国に割り当てる必要はまったくありません。

EFに対応するデータベースを作成させると、慣例により、関係はCASCADEDELETEに設定されます。つまり、通貨を削除すると、対応する国も削除されます。しかし、私の場合、これは私が望むものではありません。

CASCADE DELETEを無効にするために、FluentAPIでいくつかのコードを思いつきました。

modelBuilder.Entity<Country>()
            .HasRequired(cou => cou.Currency)
            .WithOptional()
            .WillCascadeOnDelete(false);

私はこれが意味すると思いました:すべての国は通貨を必要とします。また、この通貨には0、1つ以上の国が割り当てられている場合があります(オプション)。また、通貨を削除するたびに、対応する国(存在する場合)はカスケード削除されません。

驚いたことに、対応する通貨を削除した場合でも、指定されたアプローチで国をカスケード削除します。誰かが私が恋しいものを教えてもらえますか?

4

1 に答える 1

5

まず、国の必須フィールドとして通貨を指定したため、通貨を削除することはできません。[必須]を削除する必要があります。

次に、モデル ビルダーには次のものが必要です。

modelBuilder.Entity<Country>()
            .HasRequired(cou => cou.Currency) //note optional, not required
            .WithMany(c=>c.Countries)         //define the relationship
            .WillCascadeOnDelete(false);

3 番目に、削除するエンティティへの参照をその子から明示的に削除する必要があります。

 Currency c = context.Currencies.FirstOrDefault();

                c.Countries.Clear(); //these removes the link between child and parent

                context.Currencies.Remove(c);

                context.SaveChanges();

[編集]翻訳で何かが失われているのではないかと思うので、カスケードのない削除がどのように機能するかを示す完全なコードを見つけてください。

public class Country{
  [Key]
  public Guid ID { get; set; }

  public virtual Currency Currency { get; set; }
}

public class Currency{
  [Key]
  public Guid ID { get; set; }

  public virtual ICollection<Country> Countries { get; set; }
}


public class MyContext : DbContext{
  public DbSet<Currency> Currencies { get; set; }
  public DbSet<Country> Countries { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder){
    modelBuilder.Entity<Country>()
     .HasRequired(country => country.Currency)
     .WithMany(currency => currency.Countries)
     .WillCascadeOnDelete(false);
  }
}

class Program{
  static void Main(string[] args){
    Database.DefaultConnectionFactory = new   SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");

    Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());

    using (MyContext context1 = new MyContext()){
      Currency c = new Currency{ID = Guid.NewGuid()};

      context1.Currencies.Add(c);

      c.Countries = new List<Country>();

      c.Countries.Add(new Country{ID = Guid.NewGuid()});

      context1.SaveChanges();
   }

   using (MyContext context2 = new MyContext()){
     Currency c = context2.Currencies.FirstOrDefault();

     context2.Currencies.Remove(c);

     //throws exception due to foreign key constraint
     //The primary key value cannot be deleted 
     //because references to this key still exist.   
     //[ Foreign key constraint name = Country_Currency ]

     context2.SaveChanges();
    }          
  }
}

必要な外部キーを削除すると、保存時にエラーが発生します。

于 2011-03-23T09:29:56.793 に答える