[英]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.