我正在使用Entity Framework,并希望在数据库中插入一个对象,该对象引用了DB中尚不存在的另一个对象(但外键已知)。
简单示例:假设我有两个表,Books
(由其ISBN标识)和Purchases
。我希望能够插入购买,即使尚未在数据库中设置该书:
public class Book
{
[Key]
public virtual string ISBN { get; set; }
protected virtual IEnumerable<Purchase> purchases { get; set; }
public virtual string author { get; set; }
public virtual string title { get; set; }
// .....
}
public class Purchase
{
[Key]
protected virtual int id { get; set; }
public virtual Book book { get; set; }
public virtual double price;
}
从概念上讲,这很容易:Purchase
表将有一个外键,即书的ISBN。因此,在常规SQL中,我可以将ISBN插入此字段,稍后将该书添加到books表中。
在EF / C#中,我想不出一个简单的方法。 Purchase
类引用Book
类,因此我不能直接在此处使用ID(ISBN)。
我能做的是创建一个虚拟图书对象并使用它来插入购买。问题是Entity Framework自动将虚拟书对象插入到表中,我想避免这种情况:
var dummyBook = new Book();
dummyBook.isbn = "978-0141354217";
var purchase = new Purchase();
purchase.price = 99.95;
purchase.book = dummyBook;
dbContext.Purchases.Add(purchase);
// Should add the purchase to the DB, but NOT the book!
// Unfortunately, EF adds both automatically...
dbContext.SaveChanges();
有没有办法做到这一点?
谢谢!
答案 0 :(得分:5)
尽管ISBN(应该)是唯一的并且似乎是主键的良好候选者,但使用任何自然键作为数据库中的主键绝不是一个好习惯。
详细信息:http://en.wikipedia.org/wiki/Natural_key
因此,一旦ISBN不是您的主键,而只是一个字符串字段,您就可以按照自己的意愿行事:在没有图书记录的情况下插入特定ISBN的购买。在这种情况下,您将不具有virtual Book
类的Purchase
属性。您可以用以下内容替换它:
public Book GetBook (string isbn, DbContext context)
{
return context.Books.Where(x => x.ISBN == isbn).FirstOrDefaul();
}
所有这一切都没有讨论为什么你购买了一本在数据库中不存在的书。