0

プロジェクトでコード ファースト データベース モデルを使用しています。多対多の関係挿入の問題で立ち往生しています。これが私のデータベーススキーマです:

public class Question
{
  public int Id { get; set; }
  .....
  .......

  [CustomRequiredValidation]
  Public virtual ICollection<Tag> Tags { get; set; }
}

public class Tag
{
  public int Id { get; set; }
  public string Name { get; set; }
  public DateTime CreateDate { get; set; }
  public DateTime LastEditDate { get; set; }
  .....
  .......


  Public virtual ICollection<Question> Questions { get; set; }
}

フォーム投稿で、タグを含む質問オブジェクトを送信しています。ただし、タグ オブジェクトには、既に保存されているタグの名前と ID のみが含まれます。質問とタグの間の多対多のリレーショナル テーブルもエントリを取得できるように、質問オブジェクトをデータベースに挿入する方法を教えてください。

編集 :

ナビゲーション コレクション プロパティ ( Tags in Question エンティティ)に検証属性を追加しています。これは、質問のタグを検証する正しい場所ですか??

4

1 に答える 1

2

できることは、Tag変更を保存する前にオブジェクトをコンテキストにアタッチすることです。を使用してこれを行いますcontext.Tags.Attach(tag)。そうすれば、Entity Framework はエンティティが既に存在することを認識し、重複を挿入しようとしません。

これを示すコンソール アプリケーションを次に示します。

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

class Program
{
    static void Main(string[] args)
    {
        using (MyContext ctx = new MyContext())
        {
            ctx.Database.Delete();

            Question q1 = new Question
            {
                Title = "Title1",
                Tags = new List<Tag> 
                    { 
                        new Tag {Name = "Tag1", CreateDate = DateTime.UtcNow, LastEditDate = DateTime.UtcNow },
                        new Tag {Name = "Tag2", CreateDate = DateTime.UtcNow, LastEditDate = DateTime.UtcNow }, 
                        new Tag {Name = "Tag3", CreateDate = DateTime.UtcNow, LastEditDate = DateTime.UtcNow }, 
                    }
            };

            ctx.Questions.Add(q1);
            ctx.SaveChanges();
        }

        Question q2 = new Question
            {
                Title = "Title1",
                Tags = new List<Tag> 
                    { 
                        new Tag {Id = 1, Name = "Tag1"},
                    }
            };

        using (MyContext ctx = new MyContext())
        {
            foreach (Tag t in q2.Tags)
            {
                DbEntityEntry<Tag> entry = ctx.Entry(t);
                if (entry.State == System.Data.EntityState.Detached)
                {
                    ctx.Tags.Attach(t);
                }
            }

            ctx.Questions.Add(q2);
            ctx.SaveChanges();
        }
    }
}

public class Question
{
    public int Id { get; set; }

    public string Title { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime LastEditDate { get; set; }
    public virtual ICollection<Question> Questions { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Tag> Tags { get; set; }
    public DbSet<Question> Questions { get; set; }
}

このコンソール アプリケーションを実行すると、2 番目の質問と最初のタグの間の新しいリンクが QuestionsTag テーブルに挿入されていることがわかります。

于 2013-08-29T10:48:24.377 に答える