“已经尝试附加或添加一个非新的实体,可能是从另一个DataContext加载的。这是不受支持的。”

时间:2009-11-14 09:42:54

标签: asp.net-mvc database linq-to-sql

当我运行以下代码时:

public ActionResult Complete()
        {
            try
            {
                VeriTabanDataContext db = new VeriTabanDataContext();
                db.Persons.InsertOnSubmit(_person);
                db.SubmitChanges();
                return View(_person);
            }
            catch (Exception ex)
            {
                return RedirectToAction("Error", ex);
            }
        }

我在SubmitChanges();

上得到了Exception
"An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext.  This is not supported."
  • 这里“_person”对象来自Session,是一个很好的站立。注意:_person是多步向导的结果,这是我向数据库添加新Person对象的地方。
  • 我的Person表有9个关系,我不能为每个人添加版本列,正如一些极客所建议的那样
  • 我已经对这个问题进行了很多调查,花了2天时间仍无法解决。其他建议的一些解决方法无法解决我的问题,而其他解决方案似乎只是肮脏的解决方法。你是否有专家为这个问题提供了一个很好的解决方案,考虑到Person类有很多关系,而且在表中添加一个列是不行的。
  • 我还想注意,我曾尝试使用'db.Persons.Attach(_person)'并设置db.DeferredLoadingEnabled = false;这时候我没有得到任何异常,但数据没有保存到DB

2 个答案:

答案 0 :(得分:2)

我创建了一个名为applicationController的类,它派生自Controller。然后我让我的所有控制器类派生自此。 applicationController类有一个constrcutor,它可以在整个应用程序中使用我的存储库(或实例中的datacontext)的新实例:

     public class ApplicationController : Controller
     {
          private VeriTabanDataContext _datacontext;

          public ApplicationController() : this(new VeriTabanDataContext())
          {
          }

          public ApplicationController(VeriTabanDataContext datacontext)
          {
               _datacontext = datacontext;
          }

          Public VeriTabanDataContext DataContext
          {
               get { return _datacontext; } 
          }
     }

然后您可以在所有控制器中使用它

public class MyController : ApplicationController
{
     public ActionResult Complete()        
     {            
           DataContext.Persons.InsertOnSubmit(_person);              
           DataContext.SubmitChanges();                
           return View(_person);            
     }
}

目前没有安装VS的电脑上没有测试此代码....

希望这可以解决问题-Mark

答案 1 :(得分:1)

你能做到以下几点:

var foundPerson = db.Person.FirstOrDefault( p => p.Id == _person.Id);

if(foundPerson == null)
{
  db.InsertOnSubmit(_person);
}else{
  Mapper.Map(_person,foundPerson);
}

db.SubmitChanges();
return View(_person);

我使用AutoMapper从一个实体映射到另一个实体。为此,请将AutoMapper的引用添加到您的项目中,并在启动代码中添加您需要配置映射的应用程序,以便上述工作所需:

Mapper.CreateMap<Person, Person>().ForMember(src => src.Id, opt => opt.Ignore());