当这是一个关系时从 ObjectStateEntry 检索实体

Retrieving the entities from the ObjectStateEntry when this is a relationship

我基于 ASP.NET MVC 和 EF Code First 开发我的解决方案。

我有以下型号类:

public class Request
{
    [Key]
    public virtual int RequestID { get; set; }
    public virtual string BudgetNumber { get; set; }
    public virtual string SiteCustom { get; set; }
    public virtual Vehicle Vehicle { get; set; }
}

public class Vehicle
{
    public int VehicleID { get; set; }
    public string DesignationFr { get; set; }
    public string DesignationNl { get; set; }
    public string DesignationEn { get; set; }
}

我需要记录用户修改。例如,如果用户更改了请求的 SiteCustom 值,我可以使用下面的代码轻松跟踪它。所以在 SaveChanges 中我拦截了每一个添加和修改的条目。

    public override int SaveChanges() 
    {
        ChangeTracker.DetectChanges(); // Important!
        System.Data.Objects.ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext;
        List<ObjectStateEntry> objectStateEntryList = ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified).ToList();

        foreach (ObjectStateEntry entry in objectStateEntryList)
        {
            if (entry.IsRelationship)
            {

            }
            if (!entry.IsRelationship)
            {
                if (entry.Entity is Request) 
                {
                    var request = (Request)entry.Entity;
                    ...
                }
            }
        }
        return base.SaveChanges();
    }

正如您在上面的代码中看到的,当条目不是关系时,我可以轻松地检索它背后的实体。

我的问题: 当用户修改请求的 Vehicle 属性 这是一个关系,我没有成功检索实体当这是一段关系。我的意思是不仅要检索关系的两个部分的键值,还要检索实体的所有字段。可能吗?

我明白了。您必须使用 Include 来跟踪更改。例如:

var re = ctx.Requests.Include(i => i.Vehicle).Where(i => i.RequestID == 1).FirstOrDefault(); //do no use find
//var re = ctx.Requests.Find(1);

 re.Vehicle.DesignationEn = "asdfasdfa";
 re.Vehicle.DesignationFr = "1qweqweqweq";

 ctx.SaveChanges();

上下文:

this.ChangeTracker.DetectChanges();

var objectContext = ((IObjectContextAdapter)this).ObjectContext;

var entries = objectContext
   .ObjectStateManager
   .GetObjectStateEntries(EntityState.Modified | EntityState.Added | EntityState.Deleted);

foreach (var entry in entries)
{
    //you can see Vehicle changes here.
}

如果禁用 LazyLoading,您可能不会遇到这个问题。

来源:

Entity Framework won't detect changes of navigation properties

Entity Framework 4.1+ many-to-many relationships change tracking