簡體   English   中英

EF - 使用實體對象時重新插入外鍵

[英]EF - Foreign Key Reinserted if Entity Object is Used

因此,當我創建在從DB檢索但是來自不同DB上下文的另一個對象上具有FK引用的對象時,我遇到了EF的這個問題(請參閱GetBlog方法)。 問題是每當我嘗試將這個FK引用與主對象一起插入時,就會重新創建FK引用。

一個解決方案是我可以使用工作的FK對象的ID,但我想知道是否可以使用整個對象進行插入,如下例所示,而不復制FK對象。

我嘗試了db.Blogs.Attach(fkBlog),但這沒有幫助。 也沒有將對象狀態設置為已添加/未更改。 有任何想法嗎?

    public static void Main(string[] args)
    {
        using( var db = new BloggingContext() )
        {
            for( int i = 0; i < 10; ++i )
            { 
                var blog = new Blog() { Name = i.ToString(), Description = "Desc", Url = String.Format( "http://{0}", i ) };

                db.Blogs.Add(blog);
                db.SaveChanges();
            }

            for( int i = 0; i < 10; ++i )
            { 
                var fkBlog = GetBlog();

                var post = new Post()
                {
                    Blog = fkBlog,
                    Content = String.Format("Blog Content {0}", i),
                    Title = String.Format("Blog Title {0}", i)
                };

                db.Posts.Add(post);
                db.SaveChanges();
            }
        }
    }

    public static Blog GetBlog()
    {
        using( var db = new BloggingContext() )
        {
            return db.Blogs.OrderBy( x=>Guid.NewGuid() ).FirstOrDefault();
        }
    }

如果我使用attach方法(剛剛加載實體),我收到以下錯誤:

附加“...博客”類型的實體失敗,因為同一類型的另一個實體已具有相同的主鍵值。 如果圖中的任何實體具有沖突的鍵值,則在使用“附加”方法或將實體的狀態設置為“未更改”或“已修改”時,可能會發生這種情況。 這可能是因為某些實體是新的並且尚未收到數據庫生成的鍵值。 在這種情況下,使用“添加”方法或“已添加”實體狀態來跟蹤圖形,然后根據需要將非新實體的狀態設置為“未更改”或“已修改”。

Edit2:附加實際上失敗了因為我試圖在for循環中附加對象。 如果我只將每個博客附加一次,或者如果我在保存所有作品后總是取出該對象。

不幸的是,內聯不是我的選擇。 我依賴外部數據提供商。

您應該使用相同的上下文對象:

public static void Main(string[] args)
{
    using( var db = new BloggingContext() )
    {
        for( int i = 0; i < 10; ++i )
        { 
            var blog = new Blog() { Name = i.ToString(), Description = "Desc", Url = String.Format( "http://{0}", i ) };

            db.Blogs.Add(blog);
            db.SaveChanges();
        }

        for( int i = 0; i < 10; ++i )
        { 
            var fkBlog = db.Blogs.OrderBy( x=>Guid.NewGuid() ).FirstOrDefault();

            var post = new Post()
            {
                Blog = fkBlog,
                Content = String.Format("Blog Content {0}", i),
                Title = String.Format("Blog Title {0}", i)
            };

            db.Posts.Add(post);
            db.SaveChanges();
        }
    }
}

或者為這兩個操作創建兩個完全獨立的上下文:

public static void Main(string[] args)
{
    using( var db = new BloggingContext() )
    {
        for( int i = 0; i < 10; ++i )
        { 
            var blog = new Blog() { Name = i.ToString(), Description = "Desc", Url = String.Format( "http://{0}", i ) };

            db.Blogs.Add(blog);
            db.SaveChanges();
        }
    }

    using( var db = new BloggingContext() )
    {
        for( int i = 0; i < 10; ++i )
        { 
            var fkBlog = GetBlog();
            db.Context.Attach(fkBlog);

            var post = new Post()
            {
                Blog = fkBlog,
                Content = String.Format("Blog Content {0}", i),
                Title = String.Format("Blog Title {0}", i)
            };

            db.Posts.Add(post);
            db.SaveChanges();
        }
    }
}

Rik有一點 - 當你已經打開一個DbContexts時,不需要使用多個DbContexts 如果你仍然需要GetBlog方法,你只需使用一個接受DbContext作為參數的內部方法就可以解決這個問題:

public static void Main(string[] args)
{
    using( var db = new BloggingContext() )
    {
        for( int i = 0; i < 10; ++i )
        { 
            var blog = new Blog() { /* as before */ };
            db.Blogs.Add(blog);
            db.SaveChanges();
        }

        for( int i = 0; i < 10; ++i )
        { 
            var fkBlog = GetBlog(db);

            var post = new Post()
            {
                /* as before */
            };

            db.Posts.Add(post);
            db.SaveChanges();
        }
    }
}

public static Blog GetBlog()
{
    using(var db = new BloggingContext())
    {
        return GetBlog(db);
    }
}

private static Blog GetBlog(BloggingContext db)
{
    return db.Blogs.OrderBy(x=>Guid.NewGuid()).FirstOrDefault();
}

暫無
暫無

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

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