3
I created the following structure in SQL Server:
Using Entityframework with Code-First the classes stayed that way:
[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 that MasterId
for being null (int?
).
Still, setting the Foreign key raised in Child
to not delete in cascade (setando In Action) expected that when trying to delete a record on Master
, which has already been related to Child
, generate a Exception.
Mindful of 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; }
}
So I tested this hoping to get one Exception, but it did not occur:
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.
How to force this Exception?
Missing any settings? It’s standard behavior?
To conclude, the operation being done directly in the database returns a Exception
, as expected.
Why do you want Masterid to be null?
– ramaral
Hello @ramaral! Well, of course this is just a small example of my real problem. And
MasterId
inChild
may stay a long time or never receive a reference fromMaster
,– Severo
There’s the answer to your question. Entityframework behaves like this because, when you indicate that Masterid can be null, you are indicating that you want children without parents. Entityframework has no way of guessing that you only want this in some situations.
– ramaral
@ramaral, I get it. But this must have some way to get around, since it is not the default behavior of SQL Server. As I just updated the question showing that an exception is manually generated.
– Severo
Strange! I don’t see why the behavior is different.
– ramaral