How to force an Exception when trying to delete a Master record that already contains relationship in a Child Registry?

3

I have created the following structure in SQL Server:

UsingEntityFrameworkwithCode-First,theclasseslooklikethis:

[Table("Master")] public class Master { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } } [Table("Child")] public class Child { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Description { get; set; } [ForeignKey("Master")] public int? MasterId { get; set; } public virtual Master Master { get; set; } }

See MasterId for being null ( int? ).

Still setting Foreign key created in Child to not cascade (setting No Action ) I was hoping that when I try to delete a record in Master , which has already been listed in Child , > Exception .

Addressing the fact that I have removed the cascading deletion conventions:

public class DataContext : DbContext
{
    public DataContext()
        : base("Data Source=(local); Initial Catalog=TestFK; Integrated Security=True")
    {
        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Master> Masters { get; set; }
    public DbSet<Child> Childs { get; set; }
}

SoItestedthisexpectingtoreceiveanException,butitdidnotoccur:

class Program { static void Main(string[] args) { using (var ctx = new DataContext()) { ctx.Masters.Add(new Master { Id = 22 }); ctx.Childs.Add(new Child { Description = "Teste 1", MasterId = 22 }); ctx.SaveChanges(); var versao = ctx.Masters.SingleOrDefault(x => x.Id == 22); if (versao != null) { ctx.Masters.Remove(versao); // <-- esperava que isso geraria uma exception ctx.SaveChanges(); } } } }

Otherwise, the record was deleted and the value in Child was set to null p>

How to force this Exception ?
Missing some configuration? Is it a default behavior?

To conclude, the operation being done directly in the database returns a Exception , as expected.

    
asked by anonymous 18.03.2015 / 16:58

1 answer

2

Is it a default behavior?

Yes. Note that your Master (the parent record) may be null in the child (it is called an "orphaned record"), so there would be no reason to generate an exception since your bank allows this exclusion. What the Entity Framework does is to arrange the records for you to ensure relational consistency.

In this case, raising exception would be a business rule:

class Program
{
    static void Main(string[] args)
    {
        using (var ctx = new DataContext())
        {
            ctx.Masters.Add(new Master { Id = 22 });
            ctx.Childs.Add(new Child { Description = "Teste 1", MasterId = 22 });
            ctx.SaveChanges();

            var versao = ctx.Masters.SingleOrDefault(x => x.Id == 22);

            if (ctx.Childs.Any(c => c.MasterId == versao.Id)) {
                throw new Exception("Não é possível excluir registro pai que tenha filhos.");
            }

            // Comentei porque SingleOrDefault dá exceção quando o registro vem nulo, 
            // então esse condicional não faz muito sentido.
            // if (versao != null)
            // {
                ctx.Masters.Remove(versao); // <-- esperava que isso geraria uma exception
                ctx.SaveChanges();
            // }
        }
    }
}

About the exception

The Entity Framework first sets MasterId to Child to null before exiting Master because it knows the relationship and knows it has a foreign key there.

    
18.03.2015 / 17:10