实体框架:插入一个具有外键的对象,该外键是已知的,但不是';DB中还不存在
本文关键字:不存在 DB 对象 插入 框架 实体 一个 | 更新日期: 2023-09-27 18:29:48
我正在使用实体框架,并希望将一个对象插入到数据库中,该对象引用了数据库中还不存在的另一个对象(但外键已经知道)。
简单的例子:假设我有两个表,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)。
我可以做的是创建一个虚拟图书对象,并使用它插入购买内容。问题是实体框架也会自动将伪书对象插入到表中,我想避免这种情况:
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();
有办法做到这一点吗?
谢谢!
尽管ISBN是(应该)唯一的,而且似乎是主键的一个很好的候选者,但在数据库中使用任何自然键作为主键从来都不是一个好的做法。
此处提供详细信息:http://en.wikipedia.org/wiki/Natural_key
因此,一旦ISBN不是你的主键,而是一个字符串字段,你就可以随心所欲:在没有图书记录的情况下插入对特定ISBN的购买。在这种情况下,您将没有Purchase
类的virtual Book
属性。你可以用这样的东西来代替它:
public Book GetBook (string isbn, DbContext context)
{
return context.Books.Where(x => x.ISBN == isbn).FirstOrDefaul();
}
所有这些都不需要讨论为什么你会购买一本DB中不存在的书。