【发布时间】:2015-10-14 15:37:43
【问题描述】:
假设一个简单的数据模型由两个表组成,Book 和 Author,通过外键约束“Book.AuthorId = Author.Id”相关。
现在假设你有一些简单的书籍清单:
Title Author
---------------------------------------------------------
The Selfish Gene Richard Dawkins
Why Is Sex Fun Jared Diamond
The Ancestors Tale Richard Dawkins
如何在不进行大量往返 DB 的情况下导入这些文件?
我是 EF 的新手,但我认为它可以让我将实体添加到对象上下文中,然后即使它们尚未保存,它们也可以在该上下文中在中使用。情况似乎并非如此。原则上,我这样做:
void Import()
{
ctx = new Database();
foreach (...)
{
Import(bookTitle, authorName);
}
ctx.SaveChanges();
}
void Import(string bookTitle, string authorName)
{
var author = ctx.Authors.Single(a => a.Name == authorName);
if (author == null)
{
author = new Author();
author.Name = authorName;
ctx.AddToAuthors(author);
}
var book = new Book();
book.Author = author;
ctx.AddToBooks(book);
}
但是 EF 永远找不到我已经添加的作者,所以它每次都会创建一个新作者。因此,Dawkins 的两本书与图中的两个不同作者对象相关,这当然是错误的。
接下来,在 SaveChanges 时,EF 设法插入第一条 Book 和 Author 记录,但随后在第二条记录上崩溃并出现 PRIMARY KEY VIOLATION,因为它尝试为每个对象使用 Id = 0。
System.Data.UpdateException: An error occurred while updating the entries.
See the InnerException for details. --->
System.Data.SqlClient.SqlException: Violation of PRIMARY KEY
constraint 'PK_Book'. Cannot insert duplicate key in object 'dbo.Book'.
我试图在 MSSQL 中将 id 字段的定义更改为 INT IDENTITY(1,1),然后更新模型。让数据库定义键值总比让实体框架(或任何客户端)来做这件事要好。但这似乎根本不受支持。当我更新模型时,EF 似乎没有注意到我的键是 IDENTITY 列。它只是导致
System.Data.UpdateException: An error occurred while updating the entries.
See the InnerException for details. --->
System.Data.SqlClient.SqlException: Cannot insert explicit value for
identity column in table 'Book' when IDENTITY_INSERT is set to OFF.
无论我是否在列定义从“Id INT PRIMARY KEY”切换到“Id INT IDENTITY(1,1) PRIMARY KEY”之后更新模型,都会提供确切的症状,这让我怀疑微软甚至不记得思考身份列,尽管我希望我错了!
我意识到这里确实潜伏着多个问题,但由于 Entity Framework 中的任何内容都没有按预期工作,我选择将首要问题设为“鉴于此数据模型和要导入的这些数据,使用实体框架 3.5?”
请不要建议我改用 EF 4.0,因为这超出了我的控制范围。 :)
【问题讨论】:
标签: c# .net sql-server entity-framework