Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除时实体框架抛出与引用约束冲突_C#_Entity Framework - Fatal编程技术网

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
小改动:使用ICollection而不是IList


理由:如果获取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();