10

私のモデルには、たくさんのドメインオブジェクトがあります。ユーザーオブジェクトを更新しようとすると問題が発生します。Userは、Roleオブジェクトに対して外部キー関係を持っています。外部キー値(FkRoleId)を変更せずにUser-objectを更新すると、すべて正常に機能します。しかし、更新したい現在のユーザーの役割を変更すると、次のエラーが発生します。

参照整合性制約違反が発生しました:参照制約を定義するプロパティ値が、関係のプリンシパルオブジェクトと依存オブジェクトの間で一貫していません。

ユーザーオブジェクトを更新する方法は次のとおりです。

public void Update(User user)
{
    using (var context = new DBEntities())
    { 
    context.Entry(user).State = System.Data.EntityState.Modified;
    context.SaveChanges();
    }
}

この例外を取得せずにユーザーオブジェクトを更新するにはどうすればよいですか?ユーザーを別の役割にマップするための外部キー値を変更する方法が必要です。

この場合の私のドメインクラスは次のとおりです。

public partial class User
{
public User()
{
    this.Advertisers = new HashSet<Advertiser>();
    this.Cases = new HashSet<Case>();
    this.Materials = new HashSet<Material>();
}

public int PkId { get; set; }
public int FkRoleId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public System.DateTime Created { get; set; }
public bool Active { get; set; }

public virtual ICollection<Advertiser> Advertisers { get; set; }
public virtual ICollection<Case> Cases { get; set; }
public virtual ICollection<Material> Materials { get; set; }
public virtual Role Role { get; set; }
}


public partial class Role
{
public Role()
{
    this.Users = new HashSet<User>();
}

public int PkId { get; set; }
public string Name { get; set; }
public string Description { get; set; }

public virtual ICollection<User> Users { get; set; }
}
4

2 に答える 2

29

コメントを引用するには:

でも; ナビゲーションプロパティuser.Roleをnullに設定すると、問題なく機能します。しかし、これは推奨される作業方法ですか?

はい、この場合はそうです。

userデタッチされたオブジェクト(への参照を含む)を使用して新しいコンテキストを入力することに注意する必要がありますuser.Role。状態を設定することにより、この新しいコンテキストに関連するオブジェクトと一緒にModifiedオブジェクトをアタッチします。useruser.Role

外部キーの関連付けを使用しているため(つまり、外部キーはモデルクラスのプロパティで表されます)、関係はナビゲーションプロパティとスカラープロパティFkRoleIdの2つの方法で記述されます。これらが一貫していない場合、つまりEFは、どちらが正しい関係を記述しているかを認識せず、例外をスローします。user.Roleuser.FkRoleIduser.Role.PkId != user.FkRoleId

EFに設定user.Roleすると、ユーザーとロールの関係を説明するプロパティとして単独で考慮され、例外の原因となったあいまいさが削除されます。nulluser.FkRoleId

于 2013-03-14T21:36:37.730 に答える
0

検索者の利益のために、私は同じエラーを受け取りましたが、迅速な修正を見つけました。

編集するビューにFK関係のクラスをロードしていました。変更を加えなくても、FKがドロップされ、このエラーが発生しました。修正は、FKを含むRazorビューに非表示フィールドを含めることでした。例えば

@Html.HiddenFor(model => model.ReleaseInfo.BookId)

以下にコードをコピーして、状況が類似しているかどうかを確認できるようにします。

コントローラのアクション

public ActionResult Edit(int id = 0)
        {
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            ViewBag.Id = new SelectList(db.ReleaseInfo, "BookId", "BookId", book.Id);
            return View(book);
        }

        //
        // POST: /Book/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Book book)
        {
            if (ModelState.IsValid)
            {
                db.Entry(book).State = EntityState.Modified;

                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.Id = new SelectList(db.ReleaseInfo, "BookId", "BookId", book.Id);
            return View(book);
        }

関係

Book.cs

  public class Book
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required]
        [MaxLength(100)]
        public string Title { get; set; }


        public virtual ICollection<Author> Authors { get; set; }


        public virtual ReleaseInfo ReleaseInfo { get; set; }


        public virtual ICollection<ReRelease> ReReleases { get; set; }

    }

ReleaseInfo.cs

public class ReleaseInfo
    {
        // One to one relationship uses Books Key as Key.
        [Key, ForeignKey("Book")]
        public int BookId { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        public DateTime ReleaseDate { get; set; }


        public virtual Book Book { get; set; }
    }
于 2015-09-10T14:33:35.707 に答える