实体框架:插入一个具有外键的对象,该外键是已知的,但不是';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();

有办法做到这一点吗?

谢谢!

实体框架:插入一个具有外键的对象,该外键是已知的,但不是';DB中还不存在

尽管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中不存在的书。