如何解决用于软删除的 EF 6.0 拦截器,具有多对多关系
我正在使用 EF 6.0 Code First 实现软删除。我已经使用 2016 年的这篇博文实现了:
[https://marisks.net/2016/02/27/entity-framework-soft-delete-and-automatic-created-modified-dates/][1]
然而,它不包括多对多关系。我在任何地方都找不到处理多对多的帮助。我已经用谷歌搜索了我的大脑。
以下是我的课程的相关部分: 密钥分发
public class Keydistribution : ITypeNameProvider
{
public Keydistribution()
{
EquipmentAreas = new List<EquipmentArea>();
///...
}
///...
public virtual List<EquipmentArea> EquipmentAreas { get; set; }
///...
public virtual bool Active { get; set; } = true;
///...
}
设备面积
public class EquipmentArea : ITypeNameProvider
{
public EquipmentArea()
{
Keydistributions = new List<Keydistribution>();
///...
}
///...
public virtual List<Keydistribution> Keydistributions { get; set; }
public virtual bool Active { get; set; } = true;
///...
}
我已经映射了连接表,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EquipmentArea>().HasMany(x => x.Keydistributions).WithMany(x => x.EquipmentAreas).Map
(x => x.ToTable("dispatchEquipmentArea_Keydistribution").MapLeftKey("dispatchEquipmentArea_Id"));
///...
}
我也尝试过 .MapRightKey。
public class SoftDeleteInterceptor : IDbCommandTreeInterceptor
{
public const string ActiveColumnName = "Active";
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
if (interceptionContext.OriginalResult.DataSpace != DataSpace.sspace &&
interceptionContext.OriginalResult.DataSpace != DataSpace.CSpace) //Added CSpace to pick up association
{
return;
}
var queryCommand = interceptionContext.Result as DbQueryCommandTree;
if (queryCommand != null)
{
interceptionContext.Result = HandleQueryCommand(queryCommand);
}
var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;
if (deleteCommand != null)
{
interceptionContext.Result = HandleDeleteCommand(deleteCommand);
}
}
private static DbCommandTree HandleDeleteCommand(DbDeleteCommandTree deleteCommand)
{
///...
}
private static DbCommandTree HandleQueryCommand(DbQueryCommandTree queryCommand)
{
DbExpression newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());
return new DbQueryCommandTree(
queryCommand.MetadataWorkspace,queryCommand.DataSpace,newQuery);
}
public class SoftDeleteQueryVisitor : DefaultExpressionVisitor
{
public override DbExpression Visit(DbScanExpression expression)
{
try
{
BuiltInTypeKind type = expression.Target.BuiltInTypeKind;
if (type == BuiltInTypeKind.AssociationSet) //Here is where I need new binding
{
return base.Visit(expression);
//New binding needed here. Cannot figure out how to do on an AssociationSet vs an EntityType
}
else
{
var table = (EntityType)expression.Target.ElementType;
if (table.Properties.All(p => p.Name != ActiveColumnName))
{
return base.Visit(expression);
}
///SKIP MANY TO MANY TABLES HERE
else if (table.Name == "dispatchEquipmentArea_Keydistribution" ||
table.Name == "EquipmentArea" ||
table.Name == "Keydistribution")
{
return base.Visit(expression);
}
else
{
DbExpressionBinding binding = expression.Bind();
return binding.Filter(
binding.VariableType
.Variable(binding.VariableName)
.Property(ActiveColumnName)
.NotEqual(DbExpression.FromBoolean(false)));
}
}
}
catch (Exception ex)
{
throw;
}
}
}
}
多对多关系的每一端都有一个“活动”列,以及它们之间的连接表。因此它们之间的关系也可以是 Active/Inactive。
我在调试过程中仔细研究了这些对象,但我不知道如何更改 AssociationSet 以将“Where Active = true”放到它上面。我已经坚持了这么久。请帮忙。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。