2011-10-20 65 views
0

我遇到一些麻烦代码优先ForeignKey的。我有一个如下所述的产品,我正在尝试用该现有产品创建一个新的LineItem。然而,当我将更改保存到我的背景下,创建了一个全新的产品,但我最初使用除了ID是新的(在分贝新纪录现在)的一个的副本。EF代码优先外键创建重复数据

这里就是我加入一个新的行项目:

public void AddItem(Product item) { 
    // checking item.Id here will return 100 
    var lineItem = new LineItem 
        { 
         CartId = this.Id, 
         Product = item, 
         ProductId = item.Id, 
         Quantity = 1 
        }; 

    _db.LineItems.Add(lineItem); 
    _db.SaveChanges(); 

    // checking lineItem.Id here returns 101 
    // also checking item.Id here now also returns 101 

    this.LineItems.Add(lineItem); 
} 


public class LineItem { 
    [Key] 
    [Required] 
    public int Id { get; set; } 

    [Required] 
    public int CartId { get; set; } 

    [Required] 
    public int ProductId { get; set; } 

    [Required] 
    public int Quantity { get; set; } 

    [ForeignKey("CartId")] 
    public virtual Cart Cart { get; set; } 

    [ForeignKey("ProductId")] 
    public virtual Product Product { get; set; } 
} 

为什么会创建一个新的产品?

+1

哪里是加载要传递的产品代码?我预计这个产品的实例不再依附于上下文,因此被视为新的记录。作为测试,在您的新LineItem上保留Product = null,并设置ProductId。 –

+0

啊,是的,这是问题所在。我正在缓存我的产品集合并使用该缓存集合中的产品。如果你做出答案,我会将你标记为答案。在附注中有什么方法可以使用我的缓存版本的产品? – DennyFerra

回答

0

按照意见,你正在使用你的产品对象的一个​​独立的副本。所以EF认为这是当它被连接(通过在LineItem.Product二传手生成的代码的新实例,并相应地将其插入。

您可以重新附上您的实体,像这样

_db.Products.Attach(product); 
1

另一种解决方案,以你的问题可能是在同样的情况下传递给AddItem方法所使用的一个,你已经添加Products。 这样,您将确保用于LineItems上下文不会脱落,和EF不会看需要添加Products(或任何其他实体为此事)一次。

最好的问候,

阿迪康斯坦丁