0

Windows Phone 7.1 アプリケーションを作成していますが、データベースに変更を送信するのに苦労しています。私のデータベースのテーブルの構造は次のとおりです。

1 日目 <-1-----*-> トレーニング セッション <-多数-----1-> スポーツ

したがって、1 日に多くのトレーニング セッションがあり、トレーニング セッションには 1 つのスポーツがあります。1 つのスポーツが多くの異なるトレーニング セッションに含まれることは自然なことです。

主キーは次のようになります: Day - DateTime TrainingSession - int (DB 生成) Sport - nvarchar(200)

Sports には、単純に属性 sportName と iconFileName があります。

Day と Sport の両方に EntitySet を配置して Associations を設定しました。TrainingSession には EntityRef と EntityRef があります。Sport に EntitySet が必要かどうかは 100% わかりません。間違っている場合は訂正してください。とりあえず、テスト用に 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 was Unhandled: 新しくないエンティティをアタッチまたは追加しようとしました。別の DataContext から読み込まれた可能性があります。これはサポートされていません。

このエラーが発生する前に、NullReferenceExceptions も取得していました。

私は解決策を探していましたが、Detach を使用したり、Attach で回避策を使用したりする人もいましたが、それを自分のコードに実装する方法がわかりませんでした。誰か助けてくれませんか?

また、NullReferenceException は、スポーツをデータベースに保存していないという事実から来ている可能性があると考えましたが、そうでしょうか?

4

1 に答える 1

0

それで私はそれをたくさんいじりました、そして今日私はついに私が探していた解決策を見つけました.

質問の仕方が悪かったようです。データベースからのクエリは含めませんでした。おそらく追加することが重要です。私の質問では、物事を単純にするために実際には多くのコードを省略しましたが、省略しすぎたようです。

とにかく、データベース構造をセットアップする方法は正しいことが判明し、何も変更する必要はありませんでした。

それで、それを機能させるために私がしたことは次のとおり
です。これは、日にはトレーニング セッションがあり、データベースにその日がないとトレーニング セッションを保存できないためです。

-ローカル変数を使用してデータ コンテキストのインスタンスを作成するだけでなく、データ コンテキストを使用する必要がある場所に using ステートメントを追加しました。これにより、datacontext が using ステートメントのスコープ内にのみ存在することが保証されます。

(その日の 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);
}

次に、トレーニング セッションで 1 日を埋める方法の変更は次のようになります。

- 新しいデータ コンテキストをインスタンス化する using ステートメントを開きます。次に、データベースにアクセスして、すべてのスポーツのリストと、更新する必要のある日付を取得します。dayItemParameter で更新する必要がある日を見つけます。(データベースから取得するとコレクションが得られることに注意してください。)

- 新しいトレーニング セッションを作成し、そのプロパティを入力します。データベースから取得した日はトレーニング セッションのプロパティの値であることに注意してください。これは、トレーニング セッションが日の子であり、その親日が誰であるかを知る必要があるためです。

- DayItem クラスのコンストラクターで既にインスタンス化していたことに気付いたので、EntitySet のインスタンス化を削除しました。

-最後に、すべての新しいトレーニング セッションをコレクションに追加し、InsertAllOnSubmit(collection) を使用して一度にデータベースに保存します。

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

結論:

私が抱えていた主な問題は、データベースに提出されていない日にトレーニング セッションを保存しようとしていたことでした。次の大きな問題 (他の多くの人が抱えていると思います) は、エンティティの読み取りと更新が同じデータ コンテキスト内にある必要があることです。そのため、1 日を取得するためのデータ コンテキストを作成してから、別のデータ コンテキストを使用してその日にトレーニング セッションを追加することはできません (その日の値をローカル変数に保存したとしても)。その日を取得し、トレーニング セッションをすべて同じデータ コンテキストに保存する必要があります。

現時点では、アプリケーションは動作していますが、非常に遅いです。この質問では、たった 1 日について質問していますが、実際のプログラムでは、何百日も作成しています。つまり、データベースの開閉が非常に多いということです。プロセスを最適化する方法について提案がある場合は、耳を傾けます。

この投稿が非常に長くなってしまったことを認識し、申し訳ありませんが、それを書くことで状況をより深く理解することができました。他の人にも役立つことを願っています.

于 2012-03-21T18:50:17.307 に答える