Closed
Description
openedon Mar 27, 2019
Cross-posting from dotnet/ef6#723 (comment) since the behavior repros for both EF6 and EF Core.
Note that this may be a duplicate of #14371. The models look very similar, however the repro in that case:
- Was alternatively inserting and deleting data, while on this one it only deletes
- Would deadlock in every other request, while on this one it deadlocks every time
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
namespace EF6Issue723
{
class Program
{
static void Main(string[] args)
{
using (Context ctx = new Context())
{
ctx.Database.EnsureDeleted();
ctx.Database.EnsureCreated();
List<City> cities = new List<City>() { new City() { Name = "New York" } };
for (int h = 1; h <= 50; h++)
{
string code = "A";
if (h % 2 == 0)
code = "B";
House house = new House() { Number = h, Code = code };
cities[0].Houses.Add(house);
for (int i = 0; i <= 100; i++)
house.Residents.Add(new Person() { Firstname = "A", Lastname = "B" });
}
ctx.Cities.AddRange(cities);
ctx.SaveChanges();
}
string[] to = new string[] { "A", "B" };
Parallel.ForEach(to, code =>
{
DeleteHouses(code);
});
}
private static void DeleteHouses(string code)
{
using (var ctx = new Context())
{
var todel = ctx.Houses.Where(d => d.Code == code);
if (todel != null)
{
ctx.Houses.RemoveRange(todel);
ctx.SaveChanges();
}
}
}
}
public class Context : DbContext
{
public DbSet<City> Cities { get; set; }
public DbSet<House> Houses { get; set; }
public DbSet<Person> Persons { get; set; }
public Context() : base()
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=test;Trusted_Connection=Yes;ConnectRetryCount=0");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<City>().HasMany(c => c.Houses).WithOne(c => c.City).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<House>().HasMany(p => p.Residents).WithOne(p => p.House).IsRequired().OnDelete(DeleteBehavior.Cascade);
}
}
public class City
{
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection<House> Houses { get; set; }
public City()
{
Id = Guid.NewGuid();
Houses = new List<House>();
}
}
public class House
{
public Guid Id { get; set; }
public int Number { get; set; }
public string Code { get; set; }
public virtual City City { get; set; }
public virtual ICollection<Person> Residents { get; set; }
public House()
{
Id = Guid.NewGuid();
Residents = new List<Person>();
}
}
public class Person
{
public Guid Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public virtual House House { get; set; }
public Person()
{
Id = Guid.NewGuid();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment