C# EntityFramework核心2.0.1-使用SQLite级联删除
我知道这个问题已经被问过并回答过几次了: 但是在我的例子中,我使用的是SQLite,并且没有一个解决方案是有效的。用于更新数据库的类似代码在SQL Server上的EF6中也可以使用,但除非我遗漏了一些非常明显的东西,否则在.NET标准2.0上使用SQLite的EF Core上是不起作用的。我有一个具有子联系人的父客户,正在同时保存所有联系人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
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);
}