エンティティフレームワークで親エンティティを1対多の関係で保存できますか?

c# entity-framework entity-framework-core one-to-many

質問

私は、2つのエンティティ間の単純な一対多の関係を持っています。

public class Contact
{
    public string Id { get; set; }
    public string FirstName { get; set; }
    // the children
    public List<Message> Messages { get; set; }
}

public class Message
{
    public string Id { get; set; }
    public string ContactId { get; set; }
    public string Source { get; set; }
    // the parent
    public Contact Contact { get; set; }
}

移行方法は次のとおりです

migrationBuilder.CreateTable(
                name: "Contact",
                columns: table => new
                {
                    Id = table.Column<string>(nullable: false),
                    FirstName = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Contact", x => x.Id);
                    table.UniqueConstraint("UK_Id", x => x.Id);
                });

            migrationBuilder.CreateTable(
                name: "Message",
                columns: table => new
                {
                    Id = table.Column<string>(nullable: false),
                    ContactId = table.Column<string>(nullable: true),                        
                    Source = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Message", x => x.Id);
                    table.UniqueConstraint("UK_Id", x => x.Id);
                    table.ForeignKey(
                        name: "FK_Message_Contact_ContactId",
                        column: x => x.ContactId,
                        principalTable: "Contact",
                        principalColumn: "Id");
                });

今度は、新しいContactを作成し、 Messagesプロパティに新しいMessageを追加し、問題なく保存できます。その連絡先を読み込むと、それに関連付けられたすべてのメッセージが表示されますが、問題はありません。

私はこれを逆にする方法を疑問に思っています。新しいメッセージを作成して(まだデータベースには存在しない)、 Contactプロパティを新しい連絡先オブジェクトに設定して保存します。私は外部キーの制約に陥ります(これは意味があります。連絡先が保存されるまでメッセージを保存できません)。しかし、私はエンティティのフレームワークが関係を把握し、メッセージのに連絡先を挿入することを知るのに十分にスマートであると考えました。間違った設定をしていますか?

更新

ここで私が過ごそうとしている単体テストです

    [TestMethod]
    public void ShouldSaveEntityParentRelationshipsCorrectly()
    {
        var message = new Message
        {
            Id = "2848"
            , IsUrgent = true
            , MessageType = MessageType.Inbox
            , Note = "One ring to rule them all"
            , Contact = new Contact
            {
                Id = "454545"
                , FirstName = "Frodo"
                , LastName = "Baggins"
            }
        };

        service.Save(message); //Foreign key constraint error

        var entity = service.Find<Message>()
            .Include(c => c.Contact)
            .First(p => p.Id == "2848");

        Assert.AreEqual("Frodo", entity.Contact.FirstName);
        Assert.AreSame(entity, message, "Messages are not the same");

        Assert.IsNotNull(entity.Contact);

        Assert.AreSame(message.Contact, entity.Contact, "Contacts are not the same");
    }

どのようなサービスがありますか。 service.Saveはボンネットの下で行います

public virtual void Save<T>(T entity) where T : class, IEntity
    {
        var context = Context();
        var entry = context.Entry(entity);
        var state = entry.State;

        if (state == EntityState.Detached)
            Add(entity);
        else if (state == EntityState.Deleted)
            Remove(entity);
        else
            Update(entity);

        SaveChanges();
    }

    public virtual void SaveChanges()
    {
        try
        {
            Context().SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            Logger.Current.Log(ex);
            throw ex;
        }
    }

    public T Add<T>(T entity) where T : class, IEntity
    {
        return Context().Set<T>().Add(entity).Entity;
    }

受け入れられた回答

Beta8以降では、 DbSet.Add()はエンティティとその子のみを追加します。 ContactMessage親であるため、最初に明示的に追加する必要があります。

    service.Save(message.Contact);
    service.Save(message);

詳細については、 https://github.com/aspnet/EntityFramework/pull/2979を参照してください


人気のある回答

使用しているEF7のバージョンによって異なります。バージョンがβ7以前の場合

以前のバージョンのEFとは異なり、現在EF7を使用しているオブジェクトに対してAdd()を呼び出すと、関連するオブジェクトは追加されません。

これはbeta8で解決されたようです。詳細はこちら



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ