EntityFramework Core 2.0.1 - Cascade Delete with SQLite

2

I know this question has been asked and answered a few times:

Specifying ON DELETE NO ACTION in Entity Framework 7?

Configuring cascade delete with EF7

But in my case I'm using SQLite and none of the solutions seem to work. Similar code to update the database works in EF6 on SQL Server, but unless I'm missing something really obvious, doesn't work on EF Core with SQLite on .NET Standard 2.0. I have a parent Customer with child Contacts and am saving them all at once.

using (var dbc = new ContactsDbContext())
{                
    var customer = dbc.Customers.First(s => s.CustomerID == ReadProperty(CustomerIDProperty).ToString());

    foreach (var item in dbc.Contacts.Where(x => x.CustomerID == ReadProperty(CustomerIDProperty).ToString()))
    {
        dbc.Contacts.Remove(item);
    }
    MapToEntity(customer);
    dbc.SaveChanges();
}

I get the following exception upon SaveChanges()

System.InvalidOperationException occurred HResult=0x80131509 Message=The instance of entity type 'Contact' cannot be tracked because another instance with the key value 'ContactID:99b44b3e-c981-4140-9198-b665d3d85600' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

I loved having the ability to turn off cascade deletes globally in prior versions of EF. This is what used to work:

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

And I've tried using these two solutions below, of which neither works for SQLite.

   foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
{
    // Also tried Cascade, and all other options
    relationship.DeleteBehavior = DeleteBehavior.Restrict;
}

AND

modelBuilder.Entity<Entity.Contact>()
    .HasOne(p => p.Customer)
    .WithMany()
    .HasForeignKey("CustomerID")
    .OnDelete(DeleteBehavior.Restrict);

Has anyone successfully used parent/child updating on SQLite? My alternative is to manually check the status on each child object before saving, but that seems unnecessary for a feature that used to work. Thanks in advance for looking at this. enter image description here

Here's my Contact and customer classes

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Contacts.Library.Data.Entity
{
    [Serializable()]
    public class Contact
    {
        [Key]
        public int PrimaryKey { get; set; }

        [Required, MaxLength(36)]
        public string ContactID { get; set; }

        [ForeignKey("CustomerID"), MaxLength(36)]
        public string CustomerID { get; set; }

        [MaxLength(50)]
        public string Name { get; set; }

        // Path back to related customer
        public virtual Customer Customer { get; set; }
    }
}

    [Serializable()]
    public class Customer
    {
        [Key]
        public int PrimaryKey { get; set; }

        [Required, MaxLength(36)]
        public string CustomerID { get; set; }

        [Required, MaxLength(50)]
        public string Name { get; set; }

        // A customer has a collection of contacts
        public virtual ICollection<Contact> Contacts { get; set; }
    }

And here's my indexes

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Name on customer is unique
        modelBuilder.Entity<Entity.Customer>().HasIndex(c => c.Name).IsUnique();

        // Add index
        modelBuilder.Entity<Entity.Customer>().HasIndex(
            customer => new { customer.CustomerID }).IsUnique(false);

        // Add index
        modelBuilder.Entity<Entity.Contact>().HasIndex(
            contact => new { contact.ContactID }).IsUnique(false);

        // Add index
        modelBuilder.Entity<Entity.Contact>().HasIndex(
            contact => new { contact.CustomerID }).IsUnique(false);

    }
c#
sqlite
entity-framework-core
.net-standard-2.0
asked on Stack Overflow Dec 3, 2017 by Burian • edited Dec 5, 2017 by Burian

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0