C# Tips

C# Tip Article

EF Code First: How to insert master/details data

Question

I have Order and OrderDetails table which has one to many relationship.

How do I define the classes for them in EF? How can I insert order and order details in one submit? 

Tip

To define master/details relationship in Entity Framework (EF) Code First, basically you need to add master object to details class. For example, you have Order (master) and OrderDetails (details). To inform EF of master/details relationship, simply add public [Order] property in OrderDetail class as shown below. This is bare minimum requirement for master/details relationship. EF will automatically create Order_Id column in OrderDetail table and use it as a foreign key.

public class OrderDetail
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public Order Order { get; set; } // Add this!

    public int ProductId { get; set; }
    public int Qty { get; set; }
}

If you want a different column name or you already have existing table with other foreign key column, you can use [ForeignKey] attribute to specify a foreign key column name. And of course, you also need to add the foreign key column in the class definition.

public class OrderDetail
{
    //...
    public int OrderId { get; set; } // This is FK
    [ForeignKey("OrderId")]   // Specify what is FK
    public Order Order { get; set; }
}

To add new OrderId to OrderDetail table, simply set Order object reference to OrderDetail.Order property. When .SaveChanges() method is called, EF will automatically set new order id to both Order and OrderDetail table. (See below answer.)

Answer

public class OrderDbContext : DbContext
{
    public OrderDbContext()
        : base("DefaultConnection")
    {
    }
    public DbSet<order> Orders { get; set; }
    public DbSet<orderdetail> OrderDetails { get; set; }
}

public class Order
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public decimal Total { get; set; }
}

public class OrderDetail
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public int OrderId { get; set; }

    [ForeignKey("OrderId")]   // if not specifed, Order_Id column will be used
    public Order Order { get; set; }

    public int ProductId { get; set; }
    public int Qty { get; set; }
}

// How to insert Order/OrderDetails 
public void CreateOrder()
{
	var db = new OrderDbContext();
	var order1 = new Order
	{
		Total = 100
	};
	db.Orders.Add(order1);

	db.OrderDetails.Add(new OrderDetail
	{
		Order = order1,
		ProductId = 1011,
		Qty = 5
	});

	db.SaveChanges();
}