当我将父实体插入存储库时,它会插入子实体的副本

时间:2013-07-14 03:52:54

标签: c# entity-framework ef-code-first code-first

好吧,我有一个奇怪的问题。我有订单,订单有购物车,购物车有购物车收藏品,其中包括产品及其数量:

订单:

public class Order : DatabaseEntity
{
    public Order(Cart cart)
    {
        Cart = cart;    
    }

    public int Id { get; set; }

    [Required]
    public Cart Cart { get; set; }

    ...
}

购物车:

public class Cart : DatabaseEntity
{                  
    public ICollection<CartItem> Items { get; set; }
    public void AddItem(Product product)
    {
       // Check is there such item, is Items null, update quantity 
       // if there is already such item bla bla
       Items.Add(new CartItem(product));
    }
    ...    
}

购物车项目:

public class CartItem : DatabaseEntity
{        
    public CartItem(Product product)
    {
        Product = product;
        Quantity = 1;
    }        

    public Product Product { get; set; }
    public int Quantity { get; private set; }        
}

问题是当我创建新订单并尝试放置它时,我在数据库中获得了重复的产品记录。为什么会这样,我从未遇到过这个问题。缺少什么? OO:

[HttpPost]
public ActionResult MakeOrder(MakeOrderViewModel makeOrderModel)
{
    ...
    var cart = Session["cart"] as Cart;
    var order = new Order(cart);
    orderRepository.PlaceOrder(order);
    ...
}

订单存储库:

public void PlaceOrder(Order order)
{
    _repository.InsertOrUpdate(order);
}

和存储库本身:

public class EFDatabaseRepository
{
    ...
    public void InsertOrUpdate<TObject>(TObject entity) where TObject : DatabaseEntity
    {
        var entry = _database.Entry(entity);            
        if(entry.State == EntityState.Detached)
        {
            // New entity
            _database.Set<TObject>().Add(entity);
        }
        else
        {
            // Existing entity
            _database.Entry(entity).State = EntityState.Modified;
        }
        Save();
    }

    private void Save()
    {
        _database.SaveChanges();
    }
}

DatabseEntity只是带有id字段的类

public class DatabaseEntity
{
    public int Id { get; set; }
}

我的数据库上下文类:

public class DataBase : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<CartItem> CartItems { get; set; }
    public DbSet<Cart> Carts { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<CartItem>().HasRequired(ci => ci.Product);
        modelBuilder.Entity<Cart>().HasMany(c => c.Items);    

        base.OnModelCreating(modelBuilder);
    }
}

1 个答案:

答案 0 :(得分:1)

取自this文件:

  

如果要添加的实体具有对其他实体的引用   尚未跟踪,然后这些新实体也将被添加到   上下文并将在下次插入数据库   调用SaveChanges。

因此,在调用Unchanged之前,您需要确保上下文跟踪SaveChanges()状态中的现有实体。

context.Entry(myExistingEntity).State = EntityState.Unchanged;

或者,您可以重构类并使用外键而不是概念级别。