Search code examples
c#asp.net-mvcentity-frameworkinversion-of-control

Changing related data in repository


There are 2 entities Order and OrderDetail, which are bound this way:

public partial class Order
{ 
    public Order()
    { 
        OrderDetails = new List<OrderDetail>();
    }
    ...
}
public class OrderDetail
{
    public long OrderDetailId { get; set; }
    public int OrderId { get; set; }

    [DefaultValue(0)]
    public int RowNumber { get; set; }
    [ForeignKey("Product")]
    public int ProductId { get; set; }
    public int Count { get; set; }
    public decimal Price { get; set; }
    [ForeignKey("ProductId")]
    public virtual Product Product { get; set; }
    public virtual Order Order { get; set; }
}

I need to change the Order and remove some details from order in service. I inject only IRepository<Order> (not IRepository<OrderDetail>)in this service.
Question is: can I do this only through IRepository<Order> (neither IRepository<OrderDetail> nor DbContext explicitely).

========= implementation of IRepository according to comment ==========

public class EFRepository<T> : IRepository<T> where T : class { 
    private readonly DBContext _context; 
    public EFRepository() { 
        _context = new DBContext(); 
    } 
    public T Add(T item) { 
        _context.Set<T>().Add(item); 
        _context.SaveChanges(); return item; 
    } 
    public T Update(T entity) { 
        _context.Entry(entity).State = EntityState.Modified;
        _context.SaveChanges(); 
        return entity; 
    }
    public void Delete(T item) { 
       if (item!=null) _context.Set<T>().Remove(item); 
       _context.SaveChanges(); 
    } 
    public T GetById(object id) { 
        return _context.Set<T>().Find(id); 
    }
    public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate = null) { 
        return (predicate == null) ? _context.Set<T>() : _context.Set<T>().Where(predicate); 
    } 

Solution

  • The solution is a key in entity OrderDetails, (remove OrderDetailId and set OrderId & RowNumber as primary composite key (thanks to one man hinted but his post was removed by moderator)

    public class OrderDetail
        {
          //  public long OrderDetailId { get; set; }
    
             [Key, Column(Order = 1)]
            public int OrderId { get; set; }
    
            [Key, Column(Order = 2)]
            public int RowNumber { get; set; }
    
            [ForeignKey("Product")]
            public int ProductId { get; set; }
            public int Count { get; set; }
            public decimal Price { get; set; }
            [ForeignKey("ProductId")]
            public virtual Product Product { get; set; }
            public virtual Order Order { get; set; }
    
        }
    

    than do following code changing data and removing needless OrderDetails

     public Order ChangeOrderSimple(Guid guid, IEnumerable<JsonModelItem> items, string Comments, bool isReserve, DateTime? DeliveryDate = null)
            {
                decimal total = 0;
                int row = 1;
                Dictionary<int, int> codes = items.ToDictionary(p => p.ProductId,p=>p.Count);
                var OrderToChange = _orders.GetAll(q => q.GuidIn1S == guid).Include(o => o.OrderDetails).FirstOrDefault();
                OrderToChange.Comments = Comments;
                OrderToChange.isReserve = isReserve;
                OrderToChange.DeliveryDate = DeliveryDate;
    
    
                var OrderDetails = OrderToChange.OrderDetails.ToList();
    
                List<OrderDetail> OrderDetailsChanged = new List<OrderDetail>();
    
                for (int i = 0; i < OrderDetails.Count; i++)
                {
                    var item = OrderDetails[i];
                    //    item = OrderD.OrderDetails[i];
                    var result = codes.ContainsKey(item.ProductId);
    
    
                    if (result)
                    {
                        OrderDetail detail = new OrderDetail
                        {
                            RowNumber = ++row,
                            ProductId = item.ProductId,
                            Count = codes[item.ProductId],
                            Price = item.Price,
                            OrderId = item.OrderId
                        };
                        OrderDetailsChanged.Add(detail);
                    }
                }
    
                OrderToChange.OrderDetails = OrderDetailsChanged;
                OrderToChange.CalculateTotal();
    
                _orders.Update(OrderToChange);
                return OrderToChange;
            }