使用 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?