C# 删除时实体框架抛出与引用约束冲突
我已声明以下实体C# 删除时实体框架抛出与引用约束冲突,c#,entity-framework,C#,Entity Framework,我已声明以下实体 public class TransactionEvent { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; } public virtual List<TransactionSignInError> SignInErrors { get; set; } } 公共类TransactionEvent { [
public class TransactionEvent
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public virtual List<TransactionSignInError> SignInErrors { get; set; }
}
公共类TransactionEvent
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共Guid Id{get;set;}
公共虚拟列表签名器{get;set;}
}
以及背景
public class TransactionAuditsDbContext : DbContext
{
public virtual DbSet<TransactionEvent> TransactionEvents { get; set; }
}
公共类事务AuditSdbContext:DbContext
{
公共虚拟数据库集事务事件{get;set;}
}
现在,当我尝试删除事务事件时,我希望相关的signError
行也被删除。我意识到,如果我在上下文中设置了cascadeondelete,那么我可以通过使用cascadeondelete来实现这一点,现在已经太迟了
如何成功删除事务?我得到了这个错误
DELETE语句与引用约束“FK_dbo.TransactionSigningErrors_dbo.TransactionEvents_TransactionEvent_Id”冲突。冲突发生在数据库“db”、表“dbo.TransactionSigningErrors”、列“TransactionEvent\u Id”中
我尝试在删除之前清除签名者
列表,这确实消除了上述错误,但在TransactionSigningErrors
表中保留了空值。您想要的是“删除时级联”:如果删除了TransactionEvent,那么您还希望删除其所有TransactionSigningError
这适用于一对多关系,但不适用于多对多关系
如果您在TransactionEvents和TransactionSigningErrors之间有一对多关系,并且您遵循了,那么您将拥有如下类
public class TransactionEvent
{
public Guid Id { get; set; }
...
// Every TransactionEvent has zero or more TransactionSignInErrors (one-to-many)
public virtual ICollection<TransactionSignInError> SignInErrors { get; set; }
}
public class TransactionSignInError
{
public Guid Id { get; set; }
...
// Every TransactionSignInError belongs to exactly oneTransactionEvent, using foreign key
public Guid TransactionEventId {get; set;}
public virtual TransactionEvent TransactionEvent { get; set; }
}
public class TransactionAuditsDbContext : DbContext
{
public DbSet<TransactionEvent> TransactionEvents { get; set; }
public DbSet<TransactionSignInError> TransactionSignInErrors {get; set;}
}
因此,您的代码有三个主要更改:
- DbContext中的数据库集是非虚拟的
- 已将表TransactionSignenErrors添加到DbContext中
- 如果这对于CascadeOnDelete还不够(先检查一下!)添加fluent API
理由:如果获取TransactionEvent及其TransactionSignerRors,
TransactionEvent.SignerRors[4]
是否具有定义的含义?如果人们无法访问他们不知道其真正含义的方法,那不是更好吗?如果要使用级联删除,则必须包含子对象:
var removingRow=_context.Set<TransactionEvent>()
.Include(x=> x.SignInErrors )
.Where(x => x.Id ==id)
.FirstOrDefault();
if(removingRow != null)
{
_context.Remove(removingRow);
_context.SaveChanges();
}
var removingRow=_context.Set()
.包括(x=>x.签名者)
.其中(x=>x.Id==Id)
.FirstOrDefault();
如果(removingRow!=null)
{
_Remove(removingRow);
_SaveChanges();
}
您的帖子带有实体框架的标签。我不确定EntityFramework6或以前的版本是如何工作的,但使用EntityFrameworkCore,您可以像这样解决您的问题-
var tEvent = dbCtx.TransactionEvents
.Include(p=> p.SignInErrors)
.FirstOrDefault(p => p.Id == id);
foreach (var error in eventx.SignInErrors)
{
dbCtx.SignInErrors.Remove(error);
}
dbCtx.TransactionEvents.Remove(tEvent);
dbCtx.SaveChanges();
研究中,似乎默认情况下应该启用级联删除?还是因为我在上下文中重写了OnModelCreating?不过,我并没有在那个里详细说明级联。你们是使用实体框架还是实体框架核心?还有,为什么你认为现在这样做太迟了?
var tEvent = dbCtx.TransactionEvents
.Include(p=> p.SignInErrors)
.FirstOrDefault(p => p.Id == id);
foreach (var error in eventx.SignInErrors)
{
dbCtx.SignInErrors.Remove(error);
}
dbCtx.TransactionEvents.Remove(tEvent);
dbCtx.SaveChanges();