0

使用 EF6 + EF 扩展进行批量删除。

在代码中我做了两件事:首先,清理所有相关实体,然后添加新的相关实体。只是为了避免检查相似性。

这个主要对象类:

[Table("distrule")]
public class Distrule: CommonEntity
{
    //other properties
    public virtual ICollection<Distrule_content> DistruleContent { get; set; }
}

[Table("distrule_content")]
public class Distrule_content
{
    [Key,Column(Order=0)]
    public int distrule_id { get; set; }
    [Key, Column(Order = 1)]
    public string IDEC { get; set; }

    [ForeignKey("distrule_id")]
    public virtual Distrule Distrule { get; set; }
    [ForeignKey("IDEC")]
    public virtual Content Content { get; set; }
}

这是删除1代码:

Db.Distrule_contents.Where(x=> x.distrule_id == DistruleId).Delete();
Db.SaveChanges();

这是删除 2 代码:

List<Distrule_content> dcs = Distrule.DistruleContent.ToList();
dcs.Select(x => { Db.Entry(x).State = System.Data.Entity.EntityState.Deleted; return x; }).ToList();
Db.SaveChanges();

在一些操作之后添加新条目:

//dc has type of List<Distrule_content> and contain new collection.
Db.Distrule_contents.AddRange(dc);
Db.SaveChanges();

因此,当我使用 delete-1 使其更快时(在某些情况下最多有 10K 个条目要删除),我收到了这个错误:

System.InvalidOperationException:对数据库的更改已成功提交,但在更新对象上下文时发生错误。ObjectContext 可能处于不一致的状态。内部异常消息:保存或接受更改失败,因为“IDS.DAL.Entities.Distrule_content”类型的多个实体具有相同的主键值。确保显式设置的主键值是唯一的。确保在数据库和实体框架模型中正确配置了数据库生成的主键。使用实体设计器进行数据库优先/模型优先配置。使用“HasDatabaseGeneratedOption”流式 API 或“DatabaseGeneratedAttribute”

当我使用 delete-2 时,一切都很好,只是时间更长。

具有 db 上下文的所有操作都在事务范围内工作,如下所示:

new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TransactionManager.MaximumTimeout });

数据库上下文如下所示:

public class DBWrapper : DbContext
{
    public DBWrapper()
        : base("Name=DefaultConnection")
    {

        var adapter = (IObjectContextAdapter)this;
        var objectContext = adapter.ObjectContext;
        objectContext.CommandTimeout = 30; // value in seconds
        // set this for faster delete/insert operations
        // reduce wait time from minute or two to 10-15 seconds
        this.Configuration.AutoDetectChangesEnabled = false;
        this.Configuration.ValidateOnSaveEnabled = false;
    }
    // dbsets...
}

如何避免此异常,因为我想将此扩展用于 EF?

4

1 回答 1

0

Delete方法是立即操作。

当您调用它时,您不需要在之后调用SaveChanges,因此您不会收到此错误。


目前尚不清楚您正在使用哪个库(您在问题中说“用于批量删除的 EF 扩展。”但最初标记为“实体框架扩展”。

免责声明:我是所有这些产品的所有者。

自 2014 年起不再支持EF Extended ,

建议搬到:

这两款产品也都有这个功能。

于 2019-07-19T10:32:25.783 回答