Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否使用实体框架更新异常?_C#_Asp.net Mvc_Entity Framework_.net 4.0 - Fatal编程技术网

C# 是否使用实体框架更新异常?

C# 是否使用实体框架更新异常?,c#,asp.net-mvc,entity-framework,.net-4.0,C#,Asp.net Mvc,Entity Framework,.net 4.0,你好, 我正在为我的ASP.NET MVC网站使用EntityFramework,但在更新时遇到一些问题 这就是我的更新代码的样子: using (BissEntities context = new BissEntities()) { if (adCategoryFilter.Id < 1) context.AddToAdCategoryFilter(adCategoryFilter); else context.Refr

你好,

我正在为我的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;
这不是我第一次遇到这个问题。首先,我认为这可能与数据库中的关系有关,但在从受影响的表中删除这些关系之后,仍然存在相同的异常

adCategoryFilter来自哪里?

adCategoryFilter被实例化(新建),然后填充来自ViewObject(来自网站)的数据。它确实具有所需的数据,如筛选器Id(将筛选器映射到db中正确的行)

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


BestReleases

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

EntityKey是id属性的一个单独的东西,其他一些东西在幕后进行。您新创建的对象缺少这些内容,这就是问题的根源

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


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

因为您使用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();
}
使用(bisenties context=new bisenties())
{
if(adCategoryFilter.Id<1)
AddObject(adCategoryFilter);
否则{
var stub=newadcategoryfilters{Id=adCategoryFilter.Id};
context.AdCategoryFilters.Attach(存根);
context.adCategoryFilter.ApplyCurrentValues(adCategoryFilter);
}
SaveChanges();
}
这被称为存根技术。

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 
简而言之,您创建了一个新实体,其实体键与您尝试更新的实体相同(在您的情况下,实体键为“Id”)

然后“附加”此存根(因此它由EF内部图跟踪),然后使用要更新的实体覆盖此存根上的值,然后保存更改

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

另外,请尽量不要在ASP.NET MVC中使用“if Id<1,这是一个添加”-如果您忘记在视图上绑定Id,它将作为0传递,因此即使您可以执行更新,您上面的代码也会尝试执行添加

相反,要更加明确-为添加/更新提供单独的操作方法


嗯。

谢谢,听起来不错。但是MVC中的UpdateModel和AutoMapper()之间有什么区别呢?不确定,我还没有看过它们的内部结构。我认为它们都使用反射,并且非常相似,实际上我使用自己的自定义反射,在自定义反射中我显式地标记要在元数据中更新的属性。这两种方法所做的基本上都是让您不用为每个属性反复编写origObject.Property=viewModel.Property——您可以这样做,它也同样有效。
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();
}