实体框架:插入一个已知的外键对象,但尚未存在于DB中

时间:2014-11-10 14:44:45

标签: c# entity-framework

我正在使用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();

有没有办法做到这一点?

谢谢!

1 个答案:

答案 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();
}

所有这一切都没有讨论为什么你购买了一本在数据库中不存在的书。