2

我在 Web 应用程序中使用 EF5 和 SQL Server 2012。我有两节课:

public partial class Topic    {
    public Topic()
    {
        this.SubTopics = new List<SubTopic>();
    }
    public int TopicId { get; set; }
    public string Name { get; set; }
    public int Number { get; set; }
    public virtual ICollection<SubTopic> SubTopics { get; set; }
}

public partial class SubTopic 
{    
    public int SubTopicId { get; set; }
    public int TopicId { get; set; }
    public string Name { get; set; }
    public string Notes { get; set; }
    public virtual byte[] Version { get; set; }
    public virtual Topic Topic { get; set; }
}

在我们的前端,我们对 SubTopic Notes 进行了更改,然后当按下 Save 按钮时,Topic 对象及其 SubTopic 对象作为 JSON 发送回 Web API 控制器。当我们检查发回的内容时,我们会看到 Notes 的新数据。当我们检查参数主题时,我们还会看到新的 Notes 数据。

public HttpResponseMessage PutTopic(int id, Topic topic)
{
        _uow.Topics.Update(topic); 
        _uow.Commit();
}

但是,使用 SQL Profiler 检查我们看不到任何更改子主题的情况。检索数据时,会返回旧的子主题数据,并且对注释的编辑会丢失。

对于这样的 Web 更新情况。EF 如何确定已更改的内容,是否有某种方法可以使它检查/比较新对象的内容,以便它可以检测到更改并更新子主题?

配置:

    DbContext.Configuration.ProxyCreationEnabled = false;
    DbContext.Configuration.LazyLoadingEnabled = false;
    DbContext.Configuration.ValidateOnSaveEnabled = false;
    DbContext.Configuration.ValidateOnSaveEnabled = true;
    DbContext.Configuration.AutoDetectChangesEnabled = false;

更新方法

    public virtual void Update(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State == EntityState.Detached)
        {
            DbSet.Attach(entity);
        }  
        dbEntityEntry.State = EntityState.Modified;
    }
4

2 回答 2

3

从 ef4.x? EF 具有检测变化的能力。它可以在离线对象模式下为您工作。

我假设您的 UoW 处理没有按照您的意愿进行,因为对象在上下文中的放置方式以及状态的管理方式。

您的主要对象是附加一个对象,然后将其设置为状态更改。但是所有的子对象呢?他们是否被加载到上下文中?自动检测更改是否需要检查?如果不在上下文中,则 EF 看不到更改。

重要的是要知道 EF 何时以及如何 跟踪 Poco 对象中 的更改跟踪更改检查自动检测设置。

this.Configuration.AutoDetectChangesEnabled = false; ////<<<<<<<<< 默认为真

适用于 EF 的模式是:

var mypoco = Context.Set<TPoco>.Find(1);  // find and LOAD your poco or sub object poco
                                          // repeat for graph or use include etc...     
                                          // now in context and changes can be tracked. (see link)
// map json fields to poco entity....
myPoco.propertyXyz = json.ValuesSent; // some mapping approach to move your values, I use this package 
// <package id="ValueInjecter" version="2.3.3" targetFramework="net45" />

// now tell EF things might have changed.
// normally not required by default, But incase your are not using tracking proxies , tell ef check for changes
// Context.Context.ChangeTracker.DetectChanges(); // uncomment when needed

Context.SaveChanged(); // will trigger detect changes in normal scenarios

EF 检查加载的实体是否有任何更改,它在首次附加时具有原始状态。所以它现在可以看到哪些属性发生了变化。它只会更新那些更改的实体,并且只会设置更改的属性。

于 2013-08-06T11:12:00.783 回答
1

看来这个问题和我昨天回答的一个问题很相似。请看我的回答

于 2013-08-06T11:09:20.970 回答