Как мне представить SubmitChanges для нескольких таблиц, связанных в LinqToSql? - PullRequest
0 голосов
/ 21 марта 2012

Я делаю приложение для Windows Phone 7.1, и у меня много проблем с отправкой изменений в мою базу данных.Вот структура таблиц в моей базе данных:

Day <-1 ----- * -> TrainingSession <-many ----- 1-> Sport

Итак,один день может иметь много тренировок, а тренировка имеет один вид спорта.Один вид спорта может присутствовать во многих различных тренировочных сессиях.

Первичные ключи выглядят так: Day - DateTime TrainingSession - int (сгенерировано DB) Sport - nvarchar (200)

Спорт будет простоимеют атрибуты sportName и iconFileName.

Я установил Ассоциации, поместив EntitySet в Day и Sport, а TrainingSession имеет EntityRef и EntityRef.Я не уверен на 100%, нужен ли Спорт EntitySet, поэтому, пожалуйста, поправьте меня, если я ошибаюсь.На данный момент я просто жестко запрограммировал некоторые виды спорта в своем классе Sport для тестирования, и вы увидите, как я извлекаю коллекцию ObservableCollection, чтобы вывести их.

Вот как я пытаюсь создать коллекцию дней.с тренировками, каждая тренировка имеет разные виды спорта:

    public void CreateDay(DateTime date)
    {
        FitPlanDataContext calendarDatabase = new FitPlanDataContext(FitPlanDataContext.ConnectionString);
        DateTime firstDate = new DateTime(date.Year, date.Month, 1);

        DayItem dayItem = new DayItem();
        dayItem.DateTime = firstDate;

        fillTestDayItemWithRandomData(dayItem);

        calendarDatabase.DayItems.InsertOnSubmit(dayItem);
        calendarDatabase.SubmitChanges();
    }

    private void fillTestDayItemWithRandomData(DayItem dayItem)
    {
        ObservableCollection<SportArt> sportArtCollection = SportArtController.GetAllSports();

        dayItem.TrainingSessions = new EntitySet<TrainingSession>();
        ObservableCollection<TrainingSession> trainingSessionCollection = new ObservableCollection<TrainingSession>();

        TrainingSession trainingSession1 = new TrainingSession();
        trainingSession1.DayItem = dayItem;
        trainingSession1.SportArt = sportArtCollection[1];
        trainingSessionCollection.Add(trainingSession1);

        TrainingSession trainingSession2 = new TrainingSession();
        trainingSession2.DayItem = dayItem;
        trainingSession2.SportArt = sportArtCollection[2];
        trainingSessionCollection.Add(trainingSession2);

        FitPlanDataContext calendarDatabase = new FitPlanDataContext(FitPlanDataContext.ConnectionString);
        calendarDatabase.TrainingSessions.InsertAllOnSubmit<TrainingSession>(trainingSessionCollection);
    }

Этот код не работает для меня, и он дает мне следующую ошибку:

NotSupportedException был Unhandled:Была предпринята попытка присоединить или добавить объект, который не является новым, возможно, был загружен из другого DataContext.Это не поддерживается.

До того, как я получил эту ошибку, я также получал NullReferenceExceptions.

Я искал решение и видел, как некоторые люди использовали Detach илиОбходные пути с Attach, но я не понял, как я мог бы реализовать его в своем коде.Может ли кто-нибудь помочь мне с этим?

Кроме того, я подумал, что исключение NullReferenceException может быть связано с тем, что я не сохраняю какие-либо виды спорта в базе данных, может ли это быть так?

1 Ответ

0 голосов
/ 21 марта 2012

Так что я много с этим возился, и сегодня я наконец нашел решение, которое искал.

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

Так или иначе, оказалось, что я правильно настроил структуру базы данных, и там ничего менять не пришлось.

Итак, вот что я сделал, чтобы заставить его работать:
-Призыв к методу, который заполняет день тренировочными сессиями, необходимыми после отправки изменений в течение дня. Это потому, что дни имеют тренировки, и я не могу сохранить тренировки без дня, который уже есть в базе данных.

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

(я изменил DateTime дня на дату, указанную в качестве параметра метода)

public void CreateDay(DateTime date)
{
    DayItem dayItem = new DayItem();
    dayItem.DateTime = date;

        using (FitPlanDataContext calendarDatabase = new FitPlanDataContext(FitPlanDataContext.ConnectionString))
        {
            calendarDatabase.DayItems.InsertOnSubmit(dayItem);
            calendarDatabase.SubmitChanges();                 
        }

    fillTestDayItemWithRandomData(dayItem);
}

Затем изменения в методе, который заполняет день тренировочными сессиями, выглядят так:

-Я открываю оператор using, где создаю новый текстовый текстовый текст. Затем я получаю доступ к базе данных, чтобы получить список всех видов спорта, а также день, который мне нужно обновить. Я нахожу день, который мне нужно обновить, с помощью dayItemParameter. (Помните, что получение из базы данных даст вам коллекцию.)

- Я создаю свои новые тренировки и заполняю их свойства. Обратите внимание, что день, который я извлек из базы данных, является значением свойства сеанса обучения, поскольку сеанс обучения является дочерним днем ​​и должен знать, кто его родительский день.

-Я удалил экземпляр EntitySet, потому что понял, что уже создал его в конструкторе класса DayItem.

- Наконец, я добавляю все новые учебные занятия в коллекцию и сразу сохраняю их все в базу данных, используя InsertAllOnSubmit (коллекция).

private void fillTestDayItemWithRandomData(DayItem dayItemParameter)
{
        using (FitPlanDataContext calendarDatabase = new FitPlanDataContext(FitPlanDataContext.ConnectionString))
        {
            ObservableCollection<SportArt> sportArtCollection;          
            var sportArts = (from SportArt sportArt in calendarDatabase.SportArts
                                 select sportArt);
            sportArtCollection = new ObservableCollection<SportArt>(sportArts);

            ObservableCollection<DayItem> dayItemCollection;
            var dayItems = (from DayItem dayItem in calendarDatabase.DayItems
                            where dayItem.DateTime == dayItemParameter.DateTime
                            select dayItem);
            dayItemCollection = new ObservableCollection<DayItem>(dayItems);

            DayItem foundDayItem = dayItemCollection[0];

            ObservableCollection<TrainingSession> trainingSessionCollection = new ObservableCollection<TrainingSession>();

            TrainingSession trainingSession1 = new TrainingSession();
            trainingSession1.DayItem = foundDayItem;
            trainingSession1.SportArt = sportArtCollection[1];
            trainingSessionCollection.Add(trainingSession1);

            TrainingSession trainingSession2 = new TrainingSession();
            trainingSession2.DayItem = foundDayItem;
            trainingSession2.SportArt = sportArtCollection[2];
            trainingSessionCollection.Add(trainingSession2);


            calendarDatabase.TrainingSessions.InsertAllOnSubmit<TrainingSession>(trainingSessionCollection);
            calendarDatabase.SubmitChanges();
        }
}

Вывод:

Основная проблема, с которой я столкнулся, заключалась в том, что я пытался сохранить тренировки в день, который не был передан в базу данных. Следующая большая проблема (которая, как мне кажется, есть у многих других) заключается в том, что чтение и обновление сущности должны быть в одном и том же текстовом тексте. Таким образом, вы не можете создать текстовый текст для извлечения дня, а затем использовать другой текстовый текст для добавления тренировки в этот день (даже если вы сохранили значение дня в локальной переменной). Вам нужно восстановить день и сохранить для него учебные занятия в одном контексте данных.

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

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

...