簡體   English   中英

實體框架單查詢插入子實體

[英]Entity framework single query insert child entity

我首先在帶有C#POCO的版本6+上使用代碼學習Entity Framework(EF)。 考慮以下示例:

public class DatabaseContext : DbContext
{
    public virtual DbSet<TextElement> Textuals { get; set; }
}

public class TextElement
{
    [Key]
    public int                              Number   { get; set; }
    public string                           Content  { get; set; }
    public virtual ICollection<TextElement> Children { get; set; }
}

我想做的是將一個新的孩子添加到現有的父母中。 在偽SQL中,我可以執行以下操作:

INSERT INTO Textuals (Content, ParentId) VALUES ("Lorem Ipsum", 42)

其中42是父記錄的ID。

在過去的一天里,我一直在網絡上搜索,以使EF在C#代碼中為我做同樣的事情。 我能找到的最好的是:

using (var context = new  DatabaseContext())
{
    var parent = new TextElement { Number = 42, Children = new List<TextElement>() };
    var child  = new TextElement { Content = "I iz kiddo" };
    context.Textuals.Attach(parent);
    parent.Children.Add(child);
    context.SaveChanges();
}

但是, Attach調用似乎也要運行查詢。 相同問題適用於按ID刪除實體,該實體也需要Attach一個Attach ,並運行不必要的查詢。

有沒有一種性能更好的替代方案可以執行我想要的操作:將子實體添加到現有父實體?

更新資料

根據Cverb的回答,我得到了以下代碼以執行所需的操作:

public class TextElement
{
    [Key]
    public int                              Number   { get; set; }
    public string                           Content  { get; set; }
    public virtual ICollection<TextElement> Children { get; set; }
    // Added custom parent id reference, MUST be nullable to allow 
    // for entries without parent
    public int?                             ParentId { get; set; }
}

現在,因為這是一個違反約定的名稱(約定規定了盡可能模糊的TextElementId ),所以我需要使用一些“流利的api”代碼來更改Context。 這明確定義了類中屬性之間的關系。

public class DatabaseContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TextElement>()
            .HasMany((e) => e.Children)        // Indicate the many relation
            .WithOptional()                    // Indicate that the many
                                               // relation is optional.
                                               // Don't require a nav prop
            .HasForeignKey((e) => e.ParentId); // The FK to use with the
                                               // relation.
    }

    public virtual DbSet<TextElement> Textuals { get; set; }
}

這也使我能夠成功地應用遷移。

您應該在TextElement實體上顯式添加ParentId

public int? ParentId { get; set; }

如果您不知道該怎么做, 此頁上的 “了解一對多關系公約”下有一些很好的信息。

然后,您只需使用以下代碼即可添加新實體。

using (var context = new  DatabaseContext())
{
    var child  = new TextElement { Content = "I iz kiddo", ParentId = 42 };
    context.SaveChanges();
}

無需將子項附加或添加到父項的“ Children ,因為Entity Framework會自行承擔更改。

您使用的方式是正確的方式...在這里,EF上下文可以為您完成所有工作:啟動事務,執行所需的插入編輯和刪除操作,最后提交更改。

順其自然

我想要做的是將一個新的孩子添加到現有的父母中

和你使用的這個SQL腳本

插入文本(內容,ParentId)值(“ Lorem Ipsum”,42)

這是應該為您工作的東西。

using (var context = new  DatabaseContext())
{
    var newTextual  = new Textuals { Number = 42, Content = "I iz kiddo" };
    context.Textuals.Attach(newTextual);
    context.SaveChanges();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM