繁体   English   中英

使用Entity-Framework更新异常?

[英]Update Exception with Entity-Framework?

嗨,

我在我的ASP.NET MVC网站上使用EntityFramework但是在更新时遇到了一些问题。

这是我的更新代码的样子:

using (BissEntities context = new BissEntities())
    {

      if (adCategoryFilter.Id < 1)
        context.AddToAdCategoryFilter(adCategoryFilter);
      else
        context.Refresh(System.Data.Objects.RefreshMode.ClientWins, adCategoryFilter);

      if (context.SaveChanges() > 0)
        return true;
    }
    return false;

执行context.Refresh时,我得到以下异常:

要刷新的对象集合中索引0处的元素具有null EntityKey属性值,或者未附加到此ObjectStateManager。

Stacktrace :    at System.Data.Objects.ObjectContext.RefreshCheck(Dictionary`2 entities, Object entity, EntityKey key)
   at System.Data.Objects.ObjectContext.AddRefreshKey(Object entityLike, Dictionary`2 entities, Dictionary`2 currentKeys)
   at System.Data.Objects.ObjectContext.RefreshEntities(RefreshMode refreshMode, IEnumerable collection)
   at System.Data.Objects.ObjectContext.Refresh(RefreshMode refreshMode, Object entity)
   at Biss.Models.FilterModel.UpdateCategoryFilter(AdCategoryFilter adCategoryFilter) in C:\Users\Snowman\Documents\Visual Studio 2010\Projects\Biss\Biss\Models\FilterModel.cs:line 86 

这不是我第一次遇到这个问题。 首先,我认为它可能与数据库中的关系有关,但在从受影响的表中删除之后,仍然存在相同的异常。

adCategoryFilter来自哪里?

adCategoryFilter是instansiated(新),然后填充ViewObject(来自网站)的数据。 它确实具有所需的数据,如过滤器ID(将过滤器映射到db中的正确行)。

请求解释为什么我会遇到这个问题以及如何解决它。

最好的祝福

因为您使用的是ASP.NET MVC,所以您在无状态环境中工作。 这意味着,一旦请求完成处理,就不再有“实体框架内存”或“图形”。

因此,您需要明确告诉EF您希望添加或更新。

这是你如何做到的:

using (BissEntities context = new BissEntities())
{
  if (adCategoryFilter.Id < 1)
    context.AdCategoryFilters.AddObject(adCategoryFilter);
  else {
     var stub = new AdCategoryFilters { Id = adCategoryFilter.Id };
     context.AdCategoryFilters.Attach(stub);
     context.AdCategoryFilters.ApplyCurrentValues(adCategoryFilter);
  }

  context.SaveChanges();
}

这被称为存根技术。

简而言之,您创建一个新实体,其实体键与您尝试更新的实体相同(在您的情况下,实体键是“Id”)。

然后,您“附加”此存根(因此它由EF内部图表跟踪),然后覆盖此存根上的值,并将您的实体更新为UPDATE,然后保存更改。

我不能使用UpdateModel ,因为我有一个多层架构并使用POCO,自定义视图模型等 - 所以我在我的服务/存储库上创建了一个自定义的“UpdateModel”方法 - 它做了一个(更复杂的)版本的以上。

也尝试不使用“如果Id <1,它是一个添加”与ASP.NET MVC - 好像你忘了绑定视图上的ID,它将被传递为0,所以即使你可以做一个更新 ,您的上述代码将尝试添加

而是更明确 - 为添加/更新提供单独的操作方法。

HTH。

而不是刷新,尝试使用类似自动映射器(或MVC控制器中的UpdateModel)之类的东西检索对象并更新其属性

EntityKey是id属性的一个独立的东西,其他一些东西在幕后进行。 你新创建的对象缺少这个问题,这就是问题所在。

模式有点像(不是C#家伙所以请原谅语法):

var context = new MyEntities();
var originalObject = context.MyObjectSet.Single(x => x.Id == viewmodel.Id);
UpdateModel(originalObject);
context.SaveChanges();

关键的区别在于新检索的对象已正确设置了EntityKey。 您可以有效地使用id属性来检测新的/现有对象,但EntityKey不仅仅是该属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM