2016-04-11 74 views
2

我使用實體框架7 RC1的,我有這些實體:INSERT語句衝突與實體框架的核心外鍵約束

public class Book 
{ 
    [Key] 
    public string BookId { get; set; } 
    public List<BookPage> Pages { get; set; } 
    public Author Author { get; set; } 
    public string Text { get; set; } 
} 

public class BookPage 
{ 
    [Key] 
    public string BookPageId { get; set; } 
    public int Number { get; set; } 
} 

public class Author 
{ 
    [Key] 
    public string AuthorId { get; set; } 
    public string FullName { get; set; } 
} 

ApplicationDbContext.cs是默認情況下,public DbSet<Book> Books { get; set; }

當我試圖插入新的圖書,這樣

var book = new Book() 
{ 
    BookId = Guid.NewGuid().ToString(), 
    Pages = new List<BookPage>() 
    { 
     new BookPage() 
     { 
      BookPageId = Guid.NewGuid().ToString(), 
      Number = 1 
     } 
    }, 
    Author = new Author() 
    { 
     AuthorId = Guid.NewGuid().ToString(), 
     FullName = "Forexample" 
    }, 
    Text = "new book" 
}; 
dbContext.Books.Add(book); 
dbContext.SaveChanges(); 

它拋出異常:

SqlException:INSERT語句與FOREIGN KEY約束「FK_Book_Author_AuthorAuthorId」衝突。

這個簡單的插入有什麼問題?我不想手動添加BookPage和Author,它是Entity Framework作業。

+0

記錄已經存在的可能。 –

+0

@AmitKumarGhosh不,數據庫爲空 –

+0

如果你的id是Guids,爲什麼使用'string'?另外,我非常肯定你必須'dbContext.BookPages.Add'這個'BookPage',並且和新的'Author'一樣。 – juharr

回答

2

在你ApplicationDbContext類,你必須添加一個DbSetAuthor類,爲BookPage類:

public class ApplicationDbContext : DbContext 
{ 
    public DbSet<Book> Books { get; set; } 

    public DbSet<BookPage> BookPages { get; set; } 

    public DbSet<Author> Authors { get; set; } 

    ... 
} 

這樣就可以改寫這樣的代碼:

var author = dbContext.Authors.Add(new Author() 
{ 
    AuthorId = Guid.NewGuid().ToString(), 
    FullName = "Forexample" 
}).Entity; 

var page = dbContext.BookPages.Add(new BookPage() 
{ 
    BookPageId = Guid.NewGuid().ToString(), 
    Number = 1 
}).Entity; 


var book = new Book.Book() 
{ 
    BookId = Guid.NewGuid().ToString(), 
    Pages = new List<BookPage>(), 
    Text = "new book" 
}; 
book.Pages.Add(page); 
book.Author = author ; 
dbContext.Books.Add(book); 
dbContext.SaveChanges(); 

反正你不應該使用Guid作爲主鍵(事實上作爲聚集索引),這是使用SQL Server的一個不好的做法。

你可以看看這篇文章瞭解更多信息:

另一種方法是使用一個標識列作爲主鍵,並添加另一列(其中將包含獨特的編號),以便您的模型看起來像這樣:

public class Author 
{ 
    public Author() 
    { 
     AuthorUid = Guid.NewGuid(); 
    } 

    public int AuthorId { get; set; } 
    public Guid AuthorUid { get; set; } 
    public string FullName { get; set; } 
} 

public class Book 
{ 
    public Book() 
    { 
     BookUid = Guid.NewGuid(); 
     Pages = new List<BookPage>(); 
    } 

    public int BookId { get; set; } 
    public Guid BookUid { get; set; } 
    public List<BookPage> Pages { get; set; } 
    public Author Author { get; set; } 
    public string Text { get; set; } 
} 

public class BookPage 
{ 
    public BookPage() 
    { 
     BookPageUid = Guid.NewGuid(); 
    } 

    public int BookPageId { get; set; } 
    public Guid BookPageUid { get; set; } 
    public int Number { get; set; } 
} 

在您的DbContext,您可以指定唯一約束:

public class BookContext : DbContext 
{ 
    public DbSet<Book> Books { get; set; } 

    public DbSet<BookPage> BookPages { get; set; } 

    public DbSet<Author> Authors { get; set; } 

    ... 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Author>().HasAlternateKey(a => a.AuthorUid); 
     modelBuilder.Entity<Book>().HasAlternateKey(a => a.BookUid); 
     modelBuilder.Entity<BookPage>().HasAlternateKey(a => a.BookPageUid); 
    } 
} 

,並添加新的實體那樣:

using (var dbContext = new BookContext()) 
{ 
    var author = dbContext.Authors.Add(new Author() 
    { 
     FullName = "Forexample" 
    }).Entity; 

    var page = dbContext.BookPages.Add(new BookPage() 
    { 
     Number = 1 
    }).Entity; 

    var book = new Book.Book() 
    { 
     Text = "new book" 
    }; 

    book.Pages.Add(page); 
    book.Author = author; 

    dbContext.Books.Add(book); 
    dbContext.SaveChanges(); 
} 
+0

我們可以避免手動添加頁面和作者到數據庫嗎? –

+0

你是什麼意思?不必將其添加到DbSet? – Thomas

+0

是的,只有創建書籍,內頁和作者,然後添加到DbSet只有書。 –

相關問題