我有一个基类,我从继承有两个零到与其他实体一对多的关系:ChangeTracker实体框架4.1 - 相关的原始值的对象
public abstract class WebObject
{
public WebObject()
{
RelatedTags = new List<Tag>();
RelatedWebObjects = new List<WebObject>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string MetaKeywords { get; set; }
public string MetaDescription { get; set; }
[InverseProperty("WebObjects")]
public virtual WebSite WebSite { get; set; }
[Required(ErrorMessage = "Every WebObject must be associated with a WebSite.")]
public Guid WebSiteId { get; set; }
public virtual ICollection<Tag> RelatedTags { get; set; }
public IList<Guid> RelatedTagIds { get; set; }
public virtual ICollection<WebObject> RelatedWebObjects { get; set; }
public IList<Guid> RelatedWebObjectIds { get; set; }
}
我没法把这些原始值在SaveChanges期间查看使用ChangeTracker的实体时的关系(RelatedWebObjects & RelatedTags)。我可以在前后看到所有的标量值,我可以看到新的关系,但我看不到旧的关系。我试过使用成员和集合方法,但这些方法只显示当前值;不是旧的。另外我不喜欢使用这些,因为它要求我知道导航属性的名称,这是不够通用的。
我可以找到关系正在改变的相关对象,但当然这些相关对象中的值不会改变,所以也没有任何帮助。
有没有一些干净的方式让我跟踪SaveChanges与ChangeTracker之间的实体之前的关系?
下面是部分代码是我的工作:
public override int SaveChanges()
{
List<AuditObject> auditTrailList = new List<AuditObject>();
foreach (DbEntityEntry entity in ChangeTracker.Entries().Where(obj => { return obj.State == EntityState.Added || obj.State == EntityState.Modified || obj.State == EntityState.Deleted; }))
{
if (!(entity.Entity is AuditObject))
{
AuditObject auditObject = new AuditObject();
auditObject.Id = Guid.NewGuid();
auditObject.RevisionStamp = DateTime.Now;
auditObject.UserName = HttpContext.Current.User.Identity.Name;
auditObject.EntityType = Utilities.GetCleanClassNameIfProxyClass(entity.Entity.GetType().Name);
if (entity.State == EntityState.Added)
auditObject.Action = EntityState.Added.ToString();
else if (entity.State == EntityState.Modified)
auditObject.Action = EntityState.Modified.ToString();
else if (entity.State == EntityState.Deleted)
auditObject.Action = EntityState.Deleted.ToString();
DbMemberEntry t1 = entity.Member("RelatedWebObjects");
// cannot find original relationship collection...
DbCollectionEntry t2 = entity.Collection("RelatedWebObjects");
// cannot find original relationship collection...
if (entity.State == EntityState.Added || entity.State == EntityState.Modified)
{
XDocument currentValues = new XDocument(new XElement(auditObject.EntityType));
foreach (string propertyName in entity.CurrentValues.PropertyNames)
{
currentValues.Root.Add(new XElement(propertyName, entity.CurrentValues[propertyName]));
}
auditObject.NewData = Regex.Replace(currentValues.ToString(), @"\r\n+", " ");
}
if (entity.State == EntityState.Modified || entity.State == EntityState.Deleted)
{
XDocument originalValues = new XDocument(new XElement(auditObject.EntityType));
foreach (string propertyName in entity.OriginalValues.PropertyNames)
{
originalValues.Root.Add(new XElement(propertyName, entity.OriginalValues[propertyName]));
}
auditObject.OldData = Regex.Replace(originalValues.ToString(), @"\r\n+", " ");
}
auditTrailList.Add(auditObject);
}
}
foreach (var audit in auditTrailList)
this.AuditObjects.Add(audit);
return base.SaveChanges();
}
相关的对象也被ObjectStateManager跟踪到,你应该能够获得它们的对象状态条目,就像你如何获得它的主要对象一样。如果您发布了您正在努力的代码,我可能会提供帮助。 –
再次感谢Morteza ...我发布了我现在正在使用的代码段 - 请原谅它的不合理性;它一直没有被重构 - 只是试图让它起作用。 我可以使用IEnumerable字符串没有任何问题的对象的标量属性:entity.OriginalValues.PropertyNames&entity.CurrentValues.PropertyNames。我遇到了entity.Collection()和entity.Member()的问题。 哪些应该用于我想要完成的工作?有没有办法使这个通用的,所以我不必硬编码的集合名称?反思也许? – DMC
我不能在明天之前尝试这个......你们中的任何一个都知道我可以如何在两个答案之间分开点?因为我认为你们都提供了非常有价值的信息。 – DMC