3

I am using EF Core with a generic repository pattern.

The Order table has a one-to-many relationship with OrderItem. OrderId is a foreign key in OrderItem.

The POCO model classes:

    public class OrderEntity
    {
        public long Id { get; set; }

        public long PaymentReference { get; set; }
        public DateTimeOffset ModifiedDate { get; set; }
        public DateTimeOffset CreatedDate { get; set; }

        public IList<OrderItemEntity> OrderItemEntities { get; set; }
    }

    public class OrderItemEntity
    {
        public long Id { get; set; }
        public long OrderId { get; set; }
        public Position Position { get; set; }
        public AlterationType Type { get; set; }
        public AlterationItemType ItemType { get; set; }
        public AlterationStatus Status { get; set; }
        public double Measurment { get; set; }
        public double AlterationCost { get; set; }
    }

My service:

    public class OrderService : Repository<OrderEntity>, IOrderService
    {
        public OrderService(SalesContext context) : base(context)
        {
        }

        public long CreateOrder(OrderEntity orderEntity)
        {
            base.Add(orderEntity);
            base.Save();

            return orderEntity.Id;
        }

        public IEnumerable<OrderEntity> FilterOrderByFilterCriteria(long Id)
        {
            return base.SelectByCriteria(item => item.Id == Id);
        }

        public IEnumerable<OrderEntity> GetAllOrders()
        {
            return base.SelectAll("OrderItem");
        }
}

Generic repository:

public class Repository<T> : IRepository<T> where T : class
{
        private readonly SalesContext _dbContext;

        public Repository(SalesContext dbContext)
        {
            _dbContext = dbContext;
        }

        public virtual T Add(T obj)
        {
            _dbContext.Set<T>().Add(obj);
            return obj;
        }

        public virtual void Update(T entity)
        {
            _dbContext.Entry(entity).State = EntityState.Modified;
            _dbContext.SaveChanges();
        }

        public virtual T Delete(T obj)
        {
            _dbContext.Set<T>().Remove(obj);
            return obj;
        }

        public virtual IEnumerable<T> SelectAll(string entityToInclude)
        {
            return _dbContext.Set<T>().Include(entityToInclude).ToList();
        }

        public virtual IEnumerable<T> SelectByCriteria(Expression<Func<T, bool>> predicate)
        {
            return _dbContext.Set<T>().Where(predicate);
        }

        public virtual string Save()
        {
            _dbContext.SaveChanges();
            return string.Empty;
        }
    }
}

How can I insert multiple order-item when I am inserting order in the same connection to the database?

4
  • 1
    At the moment, how exactly is OrderEntity being created? If you simply initialize the OrderItems.OrderItemEntities property of a new OrderEntity to a new list of OrderItems before adding it to the database, all the OrderItems in the list will also be automatically added to the database. Commented Jun 10, 2021 at 14:04
  • OrderEntity is created by calling the OrderService.CreateOrder method which calls the generic repository to persist the data. Being new to EF I do not fully understand your point. Can you please add some sample code to demonstrate it? Also, the value for orderId which is a foreign key will it be automatically populated by the Entity framework of orderItems? Commented Jun 10, 2021 at 14:13
  • How is the OrderEntity object created at the calling site before calling CreateOrder()? Is it through model binding of a post request? Or do you manually create an instance? Commented Jun 10, 2021 at 14:25
  • So the API gets a request for an order-write-model which is manually transformed into an order entity. So during the mapping, the child item for entities is also added in the request object which is then sent to OrderService. Since the order has not been inserted there is no orderId in OrderItem. Commented Jun 10, 2021 at 14:34

3 Answers 3

2

Since OrderEntity has a one-to-many relationship with OrderItemEntity and OrderEntity has a navigation property called OrderItemEntities of type IList<OrderItemEntity>, initializing this property to a new list and then adding all the child OrderItemEntity objects to this list before adding this OrderEntity to the database, it will add all the OrderItemEntity objects in that list to the database along with OrderEntity

public IActionResult Create(OrderWriteModel model)
{
    
    var orderItems = new List<OrderItemEntity>();
    foreach(var item in model.OrderItems)
    {
          OrderItemEntity orderItem = YourMappingToOrderItem(item);
          orderItems.Add(orderItem);
    }

    OrderEntity order = YourMappingToOrder(model);

    //Assign the list to the parent's property
    order.OrderItemEntities = orderItems;

    //This will not only create an order but also all the OrderItemEntity objects
    _orderService.CreateOrder(order);

     //...
}

You just need to assign to OrderEntity.OrderItemEntities. That's all the code you need.

You don't even need to assign to the foreign key. EF Core will automatically populate the required fields.

For convenience, you can also include the OrderEntity navigation property in OrderItemEntity:

public class OrderItemEntity
{
    //...
    public OrderEntity OrderEntity { get; set; }
}

This is optional.

When you fetch an order from the database, for instance, using the order Id:

context.Orders.FirstOrDefault(o => o.Id == orderId)

This will not populate the OrderItemEntities property, this will be null as related entities are not included by default. If you want to include all the OrderItemEntitys, chain a call to Include():

context.Orders
    .Include(o => o.OrderItemEntities)
    .FirstOrDefault(o => o.Id == orderId)

This will include all the children.

Sign up to request clarification or add additional context in comments.

Comments

0

If you call CreateOrder as below items will be inserted alongside order;

var newOrderId = CreateOrder(new OrderEntity (){
...
OrderItemEntities  = new List<OrderItemEntity> (){new OrderItemEntity{...}},
...
});

Comments

0

Side note: (independent of EF, but certainly appies).. Collection Properties (e.g. IList) should NEVER be null, they should always be initialized at object creation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.