2016-04-11 73 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只有书。 –

相关问题