1

私はこの EF にまったく慣れていませんが、進歩していると思います。とにかく、外部キーによって関連付けられているオブジェクトを更新する方法がわからないようです。

私のDbRelationは: ここに画像の説明を入力

そして、私は1つのメンバーLANGUAGEIDを更新しようとしています.ここに私が呼び出すコンテキストがあります:

public class ManagerBase
    {
        private static NoxonEntities _entities = null;

        public NoxonEntities Entities
        {
            get
            {
                if (_entities == null)
                    _entities = new NoxonEntities();

                return _entities;
            }
        }
    }

私が試したことはたくさんあります。これが1つです:

1)

MemberManager currentMemberManager = new MemberManager();
var Mem = currentMemberManager.MyEntities.Member.SingleOrDefault(c => c.Id == 2);
var Lang = currentLanguageManager.Entities.Language.SingleOrDefault(c => c.Id == 1);

            Mem.Language = Lang;
//Or
            Mem.LanguageId = Lang.Id;
currentMemberManager.Save(Mem);

アプローチ1では、次のようなエラーが発生します

The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

2)

//Managers uses ManagerBase class as a Base class
MemberManager currentMemberManager = new MemberManager();
currentMemberManager.Save(Globals.CurrentMember.Id, Globals.CurrentLanguage.Id);
//These Global objects coming from a Http Session
//You may also say not to keep whole member object in session which I'll not after I figure this out

Here is my SAVE method and where I have the actual problem:

public void Save(Member entity)
        {
            var Data = base.Entities.Member.First(c => c.Id == entity.Id);
                    if (Data != null)
                    {
                        Data = entity;
                        base.Entities.SaveChanges();
                    }
                }
            }

アプローチ1では、EFモデルのedmxファイルのこのコードでエラーが発生します

[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
        [DataMemberAttribute()]
        public global::System.Int32 LanguageId
        {
            get
            {
                return _LanguageId;
            }
            set
            {
                OnLanguageIdChanging(value);
                ReportPropertyChanging("LanguageId");
                _LanguageId = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("LanguageId");
                OnLanguageIdChanged();
            }
        }

そして、エラーは

Object reference not set to an instance of an object.

明らかに、私は EF のやり方が間違っています。

リレーション ID (ForeignKeyId) を適切に更新する方法を教えてください。

どうもありがとう。

4

1 に答える 1

6

はい、多くの間違った方法で EF を使用しています。まず、Arran が指摘するように、データ コンテキストを静的にしないでください。そのほうが簡単に思えることはわかっていますが、データ コンテキストは頻繁に作成および破棄されるように設計されているため、これは大きな問題です。

そうしないと、アプリケーション プールが最終的に使い果たされるまで、オブジェクト グラフが成長し続けます。さらに、同時アクセスに関するあらゆる種類の問題が発生する可能性があります。静的オブジェクトはすべてのスレッド間で共有されるため、2 人のユーザーが同時にアプリを使用している場合、両方とも同じデータ コンテキストを使用し、互いにぶつかり合うことになると想像してください。

2 つ目は、多くの理由から、最も悪名高いパターンの 1 つであるシングルトンを使用していることです。それらには用途がありますが、ほとんどの人が使用するよりもはるかにまれです.

3 番目に、エラー メッセージに基づくと、データ モデルが EF モデルと同期していない可能性があるため、混乱して例外がスローされているようです。ef モデルを更新せずにデータベース構造に変更を加えましたか? 再生成してもすべてが更新されるとは限らないことに注意してください。手動で更新するか、オブジェクトを削除して再度追加する必要がある場合があります。

第四に、あなたの本当の問題 (私を信じてください、私がレイアウトしたものも本当の問題であり、ある時点であなたの後ろを噛むでしょう) は次のコードにあります:

var Data = base.Entities.Member.First(c => c.Id == entity.Id);
if (Data != null)
{
    Data = entity;
    base.Entities.SaveChanges();
}

最初に認識しなければならないことは、EF は追跡されたオブジェクトを返し、これらのオブジェクトは EF で参照を持ち、発生した変更を追跡するということです。ここで行っているのは、オブジェクトを取得し、それを破棄して、渡された追跡されていないオブジェクトに置き換えることです。

First メソッドから返されたオブジェクトを更新する必要があり、新しいオブジェクトに置き換える必要はありません。

于 2012-09-11T16:21:53.663 に答える