gpt4 book ai didi

c# - 跟踪 Entity Framework 中与行为的多对多关系的变化

转载 作者:IT王子 更新时间:2023-10-29 04:31:37 26 4
gpt4 key购买 nike

我目前正在尝试使用 Entity Framework 的 ChangeTracker 进行审计。我正在覆盖我的 DbContext 中的 SaveChanges() 方法,并为已添加、修改或删除的实体创建日志。这是 FWIW 的代码:

public override int SaveChanges()
{
var validStates = new EntityState[] { EntityState.Added, EntityState.Modified, EntityState.Deleted };
var entities = ChangeTracker.Entries().Where(x => x.Entity is BaseEntity && validStates.Contains(x.State));
var entriesToAudit = new Dictionary<object, EntityState>();
foreach (var entity in entities)
{
entriesToAudit.Add(entity.Entity, entity.State);
}
//Save entries first so the IDs of new records will be populated
var result = base.SaveChanges();
createAuditLogs(entriesToAudit, entityRelationshipsToAudit, changeUserId);
return result;
}

这对“普通”实体非常有用。然而,对于简单的多对多关系,我必须扩展此实现以包括“独立关联”,如 this 中所述。很棒的 SO 答案,它通过 ObjectContext 访问更改,如下所示:

private static IEnumerable<EntityRelationship> GetRelationships(this DbContext context, EntityState relationshipState, Func<ObjectStateEntry, int, object> getValue)
{
context.ChangeTracker.DetectChanges();
var objectContext = ((IObjectContextAdapter)context).ObjectContext;

return objectContext
.ObjectStateManager
.GetObjectStateEntries(relationshipState)
.Where(e => e.IsRelationship)
.Select(
e => new EntityRelationship(
e.EntitySet.Name,
objectContext.GetObjectByKey((EntityKey)getValue(e, 0)),
objectContext.GetObjectByKey((EntityKey)getValue(e, 1))));
}

一旦实现,这也很有效,但仅适用于使用联结表的多对多关系。通过这种方式,我指的是关系不是由类/实体表示的情况,而只是一个包含两列的数据库表 - 每个外键一列。

但是,在我的数据模型中存在某些多对多关系,其中关系具有“行为”(属性)。在此示例中,ProgramGroup 是具有 Pin 属性的多对多关系:

public class Program
{
public int ProgramId { get; set; }
public List<ProgramGroup> ProgramGroups { get; set; }
}

public class Group
{
public int GroupId { get; set; }
public IList<ProgramGroup> ProgramGroups { get; set; }
}

public class ProgramGroup
{
public int ProgramGroupId { get; set; }
public int ProgramId { get; set; }
public int GroupId { get; set; }
public string Pin { get; set; }
}

在这种情况下,我在“正常”DbContext ChangeTracker 和 ObjectContext 关系方法中都没有看到 ProgramGroup 发生变化(例如,如果 Pin 发生变化)。但是,当我逐步执行代码时,我可以看到更改发生在 ObjectContext 的 StateEntries 中,但它的条目具有 IsRelationship=false,这当然会导致 .Where(e = > e.IsRelationship) 条件。

我的问题是,为什么多对多关系与行为没有出现在正常的 DbContext ChangeTracker 中,因为它由实际的类/实体表示,为什么它没有标记为 ObjectContext StateEntries 中的关系?此外,访问这些类型的更改的最佳做法是什么?

提前致谢。

编辑:针对@FrancescCastells 的评论,即可能未明确定义 ProgramGroup 的配置是问题的原因,我添加了以下配置:

public class ProgramGroupConfiguration : EntityTypeConfiguration<ProgramGroup>
{
public ProgramGroupConfiguration()
{
ToTable("ProgramGroups");
HasKey(p => p.ProgramGroupId);

Property(p => p.ProgramGroupId).IsRequired();
Property(p => p.ProgramId).IsRequired();
Property(p => p.GroupId).IsRequired();
Property(p => p.Pin).HasMaxLength(50).IsRequired();
}

这是我的其他配置:

public class ProgramConfiguration : EntityTypeConfiguration<Program>
{
public ProgramConfiguration()
{
ToTable("Programs");
HasKey(p => p.ProgramId);
Property(p => p.ProgramId).IsRequired();
HasMany(p => p.ProgramGroups).WithRequired(p => p.Program).HasForeignKey(p => p.ProgramId);
}
}

public class GroupConfiguration : EntityTypeConfiguration<Group>
{
public GroupConfiguration()
{
ToTable("Groups");
HasKey(p => p.GroupId);
Property(p => p.GroupId).IsRequired();
HasMany(p => p.ProgramGroups).WithRequired(p => p.Group).HasForeignKey(p => p.GroupId);
}

当这些实现时,EF 仍然不会在 ChangeTracker 中显示修改后的 ProgramGroup

最佳答案

虽然在实体关系建模理论中提到了“与属性的关系”的概念,但就 Entity Framework 而言,您的 ProgramGroup 类是一个实体。您可能在第一个代码片段中使用 x.Entity is BaseEntity 检查无意中将其过滤掉。

关于c# - 跟踪 Entity Framework 中与行为的多对多关系的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33611135/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com