L2S DataContext не синхронизирован: строка не найдена или изменена - PullRequest
3 голосов
/ 22 декабря 2010

Psssst ...!

Продолжайте читать, во что бы то ни стало. Но я могу сказать вам здесь, что проблема не имеет ничего общего с DataContext, но с внедрением зависимости. Я оставил этот вопрос, поскольку он документирует одну возможную проблему с «ошибкой строки не найдена или изменена», которая не имеет никакого отношения к конфликтам параллелизма реального мира.

Кажется, проблемы были вызваны плохо написанным внедрением зависимостей. Вернее, я начинаю верить, что по умолчанию управление жизненным циклом использует контейнер DI, который я использовал.

Проблема заключалась в том, что я использовал DataContext в качестве аргумента конструктора, предоставленного Ninject. Кажется, что поведение по умолчанию было кэшировать этот DataContext, что привело к неожиданному поведению. Я задам отдельный вопрос по этому поводу.

Во всяком случае, ниже следует мой оригинальный вопрос, который, как вы увидите, пропускает реальную причину проблемы на милю ...

Проблема

Я получаю ряд ошибок, из которых следует, что DataContext, а точнее то, как я использую DataContext, не синхронизируется.

Ошибка возникает в db.SubmitChanges (), где db - мой экземпляр DataContext. Ошибка:

Строка не найдена или не изменена.

Проблема возникает только периодически, например, добавление строки, а затем ее удаление. Если я остановлю сервер dev и перезапущу, добавленная строка будет там, и я могу удалить ее без проблем.

Т.е., похоже, что проблема связана с потерей трека DataContext добавленных строк.

ВАЖНО:

Прежде чем кто-либо проголосует за закрытие этого потока, так как он является дубликатом, я проверил профилировщик сервера sql и в SQL нет "Где 0 = 1".

Я также воссоздал файл dbml, поэтому я удовлетворен тем, что схема базы данных синхронизируется со схемой, представленной файлом dbml.

То есть, нет случаев несоответствующих обнуляемых / не обнуляемых столбцов и т. Д.

Мой диагноз (для чего он стоит):

Мне кажется, что проблема связана с тем, как я использую DataContext. Я новичок в шаблонах MVC, репозиториев и сервисов, поэтому подозреваю, что все неправильно спланировано.

Настройка

Простое приложение электронного обучения на ранних стадиях. Ученики должны иметь возможность добавлять и удалять курсы (таблица курсов) в свои пользовательские курсы.

Для этого у меня есть служба, которая получает конкретный экземпляр DataContext Dependency, внедренный в его конструктор.

Конструктор класса обслуживания:

public class SqlPupilBlockService : IPupilBlockService
{
    DataContext db;
    public SqlPupilBlockService(DataContext db)
    {
        this.db = db;
        CoursesRepository = new SqlRepository<Course>(db);
        UserCoursesRepository = new SqlRepository<UserCourse>(db);
    }
// Etc, etc
}

CoursesRepository и UserCoursesRepository являются частными свойствами класса обслуживания, которые имеют тип IRepository (просто простой универсальный интерфейс хранилища).

Код хранилища Sql:

public class SqlRepository<T> : IRepository<T> where T : class
    {
        DataContext db;
        public SqlRepository(DataContext db)
        {
            this.db = db;
        }

        #region IRepository<T> Members

        public IQueryable<T> Query
        {
            get { return db.GetTable<T>(); }
        }

        public List<T> FetchAll()
        {
            return Query.ToList();
        }

        public void Add(T entity)
        {
            db.GetTable<T>().InsertOnSubmit(entity);
        }

        public void Delete(T entity)
        {
            db.GetTable<T>().DeleteOnSubmit(entity);
        }

        public void Save()
        {
            db.SubmitChanges();
        }

        #endregion
    }

Два метода для добавления и удаления UserCourses:

Методы обслуживания для добавления и удаления пользовательских курсов:

public void AddUserCourse(int courseId)
{
    UserCourse uc = new UserCourse();
    uc.IdCourse = courseId;
    uc.IdUser = UserId;
    uc.DateCreated = DateTime.Now;
    uc.DateAmended = DateTime.Now;
    uc.Role = "Pupil";
    uc.CourseNotes = string.Empty;
    uc.ActiveStepIndex = 0;
    UserCoursesRepository.Add(uc);
    UserCoursesRepository.Save();
}

public void DeleteUserCourse(int courseId)
{
    var uc = (UserCoursesRepository.Query.Where(x => x.IdUser == UserId && x.IdCourse == courseId)).Single();
    UserCoursesRepository.Delete(uc);
    UserCoursesRepository.Save();

}

Ajax

Я использую Ajax через Ajax.BeginForm

Не думаю, что это актуально.

ASP.NET MVC 3

Я использую mvc3, но не думаю, что это актуально: ошибки связаны с кодом модели.

Ответы [ 2 ]

1 голос
/ 22 декабря 2010

Проблема возникает только периодически, например, добавив строку затем удаляя его. Если я остановлю сервер разработки и перезагрузите, добавленная строка есть и я могу удалить это без проблем.

Ваш код не показывает связь между добавленной строкой и удалением / обновлением. Ваш Add () не возвращает ссылку на объект.

Я думаю, что вы пропустили обновление (т.е. перезагрузите объект после вставки). Ваш IdCourse также является ПК в таблице?

0 голосов
/ 22 декабря 2010

Edit:

Дальнейшие исследования показали, что проблема связана с внедрением зависимости.

Проблема была связана с тем, как Dependency Injection управляет создаваемыми элементами. Google для «управления жизненным циклом» в IoC или DI. По сути, DI кэшировал аргумент конструктора DataContext, который я ввел.

Чтобы решить эту проблему с помощью Factory Pattern, см. Следующую ветку: Ninject кэширует введенный DataContext? Управление жизненным циклом?

Принятый ответ все решил.

...