C# EntityFramework核心2.0.1-使用SQLite级联删除

C# EntityFramework核心2.0.1-使用SQLite级联删除,c#,sqlite,entity-framework-core,.net-standard-2.0,C#,Sqlite,Entity Framework Core,.net Standard 2.0,我知道这个问题已经被问过并回答过几次了: 但是在我的例子中,我使用的是SQLite,并且没有一个解决方案是有效的。用于更新数据库的类似代码在SQL Server上的EF6中也可以使用,但除非我遗漏了一些非常明显的东西,否则在.NET标准2.0上使用SQLite的EF Core上是不起作用的。我有一个具有子联系人的父客户,正在同时保存所有联系人 using (var dbc = new ContactsDbContext()) { var custome

我知道这个问题已经被问过并回答过几次了:

但是在我的例子中,我使用的是SQLite,并且没有一个解决方案是有效的。用于更新数据库的类似代码在SQL Server上的EF6中也可以使用,但除非我遗漏了一些非常明显的东西,否则在.NET标准2.0上使用SQLite的EF Core上是不起作用的。我有一个具有子联系人的父客户,正在同时保存所有联系人

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();
}
我在SaveChanges()时遇到以下异常

发生System.InvalidOperationException异常 HResult=0x80131509 Message=无法跟踪实体类型“Contact”的实例,因为已跟踪键值为“ContactID:99b44b3e-c981-4140-9198-b665d3d85600”的另一个实例。附着现有实体时,请确保仅附着一个具有给定键值的实体实例

我喜欢在EF的早期版本中能够全局关闭级联删除。这就是过去的工作:

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

modelBuilder.Entity()
.HasOne(p=>p.Customer)
.有很多
.HasForeignKey(“客户ID”)
.OnDelete(DeleteBehavior.Restrict);
是否有人在SQLite上成功使用了父/子更新?我的替代方法是在保存之前手动检查每个子对象的状态,但对于以前工作的功能来说,这似乎是不必要的。提前谢谢你看这个。

这是我的联系人和客户分类

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; }
    }
使用系统;
使用System.ComponentModel.DataAnnotations;
使用System.ComponentModel.DataAnnotations.Schema;
命名空间Contacts.Library.Data.Entity
{
[可序列化()]
公共类联系人
{
[关键]
public int PrimaryKey{get;set;}
[必需,最大长度(36)]
公共字符串ContactID{get;set;}
[外键(“客户ID”),最大长度(36)]
公共字符串CustomerID{get;set;}
[MaxLength(50)]
公共字符串名称{get;set;}
//返回相关客户的路径
公共虚拟客户客户{get;set;}
}
}
[可序列化()]
公共类客户
{
[关键]
public int PrimaryKey{get;set;}
[必需,最大长度(36)]
公共字符串CustomerID{get;set;}
[必需,最大长度(50)]
公共字符串名称{get;set;}
//客户有一组联系人
公共虚拟ICollection联系人{get;set;}
}
这是我的索引

    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);

    }
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
//客户上的名称是唯一的
modelBuilder.Entity().HasIndex(c=>c.Name).IsUnique();
//添加索引
modelBuilder.Entity().HasIndex(
customer=>new{customer.CustomerID}).IsUnique(false);
//添加索引
modelBuilder.Entity().HasIndex(
contact=>new{contact.ContactID}).IsUnique(false);
//添加索引
modelBuilder.Entity().HasIndex(
contact=>new{contact.CustomerID}).IsUnique(false);
}

您确定发布了实际的异常消息吗?因为发布的内容与SQLite无关,所以cascade delete和
SaveChanges
-应该从其他方法抛出,如
Attach
Add
Update
Remove
等。谢谢Ivan。我附加了一个异常的屏幕抓图。这真的很奇怪。您是否有自定义代码覆盖
SaveChanges
?你还可以发布异常堆栈跟踪,以了解发生了什么?谢谢Ivan。没有,也没有覆盖。我将我的customer和contact类复制到帖子中,并将OnModelCreating复制到帖子中以显示索引。我最后做的是在我不使用的每个文件上使用一个int-ID,它是有效的。不知道为什么。CustomerID和ContactID是唯一的Guid。我只对整数进行了相同的尝试,得到了相同的结果。在执行
SaveChanges
时,您是否看到任何
SELECT
查询正在运行?Sqlite查询提供程序似乎在保存更改时试图从数据库中获取数据。不管它做什么,这看起来像一个严重的错误。
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; }
    }
    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);

    }