ef-code-first - EF 4.1 RC : Weird Cascade Delete

标签 ef-code-first cascading-deletes entity-framework-4.1 fluent-interface

我不得不承认,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创建对应的数据库,按照约定,关系会设置为CASCADE DELETE。换句话说:如果您删除一种货币,相应的国家也会被删除。但就我而言,这不是我想要的。

我在 FluentAPI 中想出了一些代码来禁用 CASCADE DELETE:
modelBuilder.Entity<Country>()
            .HasRequired(cou => cou.Currency)
            .WithOptional()
            .WillCascadeOnDelete(false);

我认为这意味着:每个国家都需要货币。并且该货币可能分配了零个、一个或多个国家(可选)。每当我删除货币时,相应的国家(如果有)将不会被级联删除。

令人惊讶的是,如果我删除相应的货币,给定的方法仍然会级联删除一个国家。谁能告诉我我想念什么?

最佳答案

首先,您已将货币指定为国家/地区的必填字段,因此您无法删除货币。您需要删除 [Required]。

其次,您的模型构建器需要以下内容:

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

第三,您需要明确删除对要从其子项中删除的实体的引用:
 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();
    }          
  }
}

您将在保存时出错,因为您删除的内容是必需的外键。

关于ef-code-first - EF 4.1 RC : Weird Cascade Delete,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5402964/

相关文章:

c# - 在没有 Helper 属性的情况下一对一映射 EntityFramework

MySQL - 关于删除级联问题

java - DB4O 递归删除,它实际上是如何工作的?

entity-framework-4 - 附加对象后加载属性

c# - 在 ASP.NET Core 中通过代码优先在 SQL 中使用 FileStream

c# - 在 SQL Server Compact Edition 中将 Entity Framework 代码中的种子主键首先设置为 0

mysql - 查看 MySQL Workbench 中级联删除的完整效果?

dependency-injection - 使用 Entity Framework 4.1 和 DDD 访问代码生成的 DbContext 上的存储过程

entity-framework - 数据库第一种方法中与连接表的多对多关系

c# - 在 Entity Framework 中分离和附加对象时出错