.net ChangeTracker实体框架4.1-相关对象的原始值
我有一个继承自的基类,它与其他实体有两个零到多的关系:.net ChangeTracker实体框架4.1-相关对象的原始值,.net,entity-framework-4.1,ef-code-first,change-tracking,.net,Entity Framework 4.1,Ef Code First,Change Tracking,我有一个继承自的基类,它与其他实体有两个零到多的关系: public abstract class WebObject { public WebObject() { RelatedTags = new List<Tag>(); RelatedWebObjects = new List<WebObject>(); } [Key, DatabaseGenerated(DatabaseGeneratedOptio
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; }
}
公共抽象类WebObject
{
公共WebObject()
{
RelatedTags=新列表();
RelatedWebObjects=新列表();
}
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
公共Guid Id{get;set;}
公共字符串元关键字{get;set;}
公共字符串元描述{get;set;}
[反向属性(“WebObjects”)]
公共虚拟网站{get;set;}
[必需(ErrorMessage=“每个WebObject必须与网站关联。”)]
公共Guid网站ID{get;set;}
公共虚拟ICollection RelatedTags{get;set;}
公共IList RelatedTagID{get;set;}
公共虚拟ICollection RelatedWebObjects{get;set;}
公共IList RelatedWebObjectId{get;set;}
}
在保存更改期间使用ChangeTracker查看实体时,我很难获取这些关系(RelatedWebObjects和RelatedTags)的原始值。我可以看到之前和之后的所有标量值,可以看到新的关系,但看不到旧的关系。我尝试过使用Member和Collection方法,但它们只显示当前值;不是老的。另外,我不喜欢使用它们,因为它要求我知道导航属性的名称,这不够通用
我可以找到其关系正在更改的相关对象,但是这些相关对象中的值当然不会更改,因此这也没有任何帮助
在使用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();
}
public override int SaveChanges()
{
List auditTrailList=新列表();
foreach(ChangeTracker.Entries()中的DbEntityEntry实体,其中(obj=>{return obj.State==EntityState.Added | | obj.State==EntityState.Modified | | obj.State==EntityState.Deleted;}))
{
如果(!(entity.entity是AuditObject))
{
AuditObject AuditObject=新的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”);
//找不到原始关系集合。。。
DbCollectionEntry t2=entity.Collection(“RelatedWebObjects”);
//找不到原始关系集合。。。
if(entity.State==EntityState.Added | | entity.State==EntityState.Modified)
{
XDocument currentValues=新XDocument(新XElement(auditObject.EntityType));
foreach(entity.CurrentValues.PropertyNames中的字符串propertyName)
{
currentValues.Root.Add(新的XElement(propertyName,entity.currentValues[propertyName]);
}
auditObject.NewData=Regex.Replace(currentValues.ToString(),@“\r\n+”,“”);
}
if(entity.State==EntityState.Modified | | entity.State==EntityState.Deleted)
{
XDocument originalValues=新XDocument(新XElement(auditObject.EntityType));
foreach(entity.OriginalValues.PropertyNames中的字符串propertyName)
{
添加(新的XElement(propertyName,entity.originalValues[propertyName]);
}
auditObject.OldData=Regex.Replace(originalValues.ToString(),@“\r\n+”,”);
}
Add(auditObject);
}
}
foreach(auditTrailList中的var审计)
this.AuditObjects.Add(审计);
返回base.SaveChanges();
}
因为EF change跟踪图形中的每个对象,所以您始终可以将图形中的任何实例传递给更改跟踪器,它将为您提供更改跟踪值。例如,以下代码将获取AuditObject导航属性的原始/当前值:
DbMemberEntry t1 = entity.Member("RelatedWebObjects");
// cannot find original relationship collection....
AuditObject currentAuditObject = (AuditObject) entity;
var currValues = this.Entry(currentAuditObject.RelatedWebObjects).CurrentValues;
var orgValues = this.Entry(currentAuditObject.RelatedWebObjects).OriginalValues;
或者,在处理集合类型导航属性时,可以应用相同的技巧:
DbCollectionEntry t2 = entity.Collection("RelatedWebObjects");
// cannot find original relationship collection....
foreach (WebObject item in currentAuditObject.RelatedWebObjects)
{
var currValues = this.Entry(item).CurrentValues;
}
这有点难。首先,您必须与EF提供的不同:
- 独立协会(所有多对多关系和一些一对多)
- 外键关联(所有一对一关系和一些一对多)
ObjectContext
API及其ObjectStateManager
ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
foreach (ObjectStateEntry entry = objectContext.ObjectStateManager
.GetObjectStateEntries(~EntityState.Detached)
.Where(e => e.IsRelationship))
{
// Track changes here
}
现在,您可以访问该关系的ObjectStateEntry
实例。这些实例不应修改状态
。它们将被添加、删除或保持不变,因为“修改”是过程