«Была сделана попытка присоединить или добавить объект, который не является новым, возможно, был загружен из другого DataContext. Это не поддерживается» - PullRequest
1 голос
/ 14 ноября 2009

Когда я запускаю следующий код:

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 ();

"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" взят из сессии и имеет хорошую репутацию. Примечание: _person является результатом многошагового мастера, и именно здесь я добавляю новый объект Person в БД.
  • Моя таблица Персона имеет 9 отношений, и я не могу добавить столбец версии для каждого из них, как это предлагают некоторые фанаты около
  • Я много исследовал эту проблему и потратил на нее 2 дня, но все еще не мог ее решить. Некоторые из обходных путей, которые другие предлагают, не решают мою проблему, а другие кажутся просто грязными обходными путями. У вас, экспертов, есть хорошее решение этой проблемы, учитывая, что класс Person имеет много связей, а также не разрешено добавлять столбец в таблицы.
  • Я также хочу отметить, что я пытался использовать db.Persons.Attach (_person) и установить db.DeferredLoadingEnabled = false; В этот раз я не получаю никаких исключений, но данные НЕ сохраняются в БД

Ответы [ 2 ]

2 голосов
/ 14 ноября 2009

Я создаю класс под названием 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 голос
/ 14 ноября 2009

Можете ли вы сделать следующее:

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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...