# Reading and writing data

## Storing objects

To store data to the database use `DbContext.Add(object)` as follows:

```cs
using Microsoft.EntityFrameworkCore;

var db = new InventorySystemDbContext();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();

List<Item> items =
[
    new UnitItem
    {
        Id = "M3 screw",
        PricePerUnit = 1,
        InventoryLocation = 1,
        Quantity = 1000,
        Weight = 0.001m
    },
    new BulkItem
    {
        Id = "crank oil",
        PricePerUnit = 1.5m,
        InventoryLocation = 2,
        MeasurementUnit = "l",
        Quantity = 10
    }
];

List<Inventory> inventories =
[
    new()
    {
        Id = "wind turbine parts",
        Stock = items
    },
    new()
    {
        Id = "electronics",
        Stock = []
    }
];

foreach (var inventory in inventories)
    db.Add(inventory);
db.SaveChanges();

public class InventorySystemDbContext : DbContext
{
    public DbSet<Inventory> Inventories { get; set; }
    public DbSet<UnitItem> UnitItems { get; set; }
    public DbSet<BulkItem> BulkItems { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=../../../inventory.sqlite");
    }
}

public class Item
{
    public string Id { get; set; }
    public decimal PricePerUnit { get; set; }
    public decimal Quantity { get; set; }
    public uint InventoryLocation { get; set; }
}

public class BulkItem : Item
{
    public string MeasurementUnit { get; set; }
}

public class UnitItem : Item
{
    public decimal Weight { get; set; }
}

public class Inventory
{
    public const decimal LowStockThreshold = 5;
    public string Id { get; set; }
    public List<Item> Stock { get; set; }
}
```

Now double click `Item` on the `Database` tool, to browse its contents. You will see:

:::{list-table}
:header-rows: 1
* - Id
  - PricePerUnit
  - Quantity
  - InventoryLocation
  - Discriminator
  - InventoryId
  - MeasurementUnit
  - Weight
* - crank oil
  - 1.5
  - 10.0
  - 2
  - BulkItem
  - wind turbine parts
  - l
  - null
* - M3 screw
  - 1.0
  - 1000.0
  - 1
  - UnitItem
  - wind turbine parts
  - null
  - 0.001
:::

:::{tip}
You can also add/modify/delete data using the `Database` tool in Rider.
:::

## Reading objects from a database

Typically we have a database with data inside. Using `inventory.sqlite` with inventory data inside we can read data as follows:

```cs
using Microsoft.EntityFrameworkCore;

var db = new InventorySystemDbContext();
var inventories = db.Inventories.Include(inventory => inventory.Stock).ToList();
foreach (var inventory in inventories)
    if (inventory.Id == "wind turbine parts")
        Console.WriteLine(inventory.Stock.Count);

public class InventorySystemDbContext : DbContext
{
    public DbSet<Inventory> Inventories { get; set; }
    public DbSet<UnitItem> UnitItems { get; set; }
    public DbSet<BulkItem> BulkItems { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=../../../inventory.sqlite");
    }
}

public class Item
{
    public string Id { get; set; }
    public decimal PricePerUnit { get; set; }
    public decimal Quantity { get; set; }
    public uint InventoryLocation { get; set; }
}

public class BulkItem : Item
{
    public string MeasurementUnit { get; set; }
}

public class UnitItem : Item
{
    public decimal Weight { get; set; }
}

public class Inventory
{
    public const decimal LowStockThreshold = 5;
    public string Id { get; set; }
    public List<Item> Stock { get; set; }
}
```
The code outputs the number of items in one of the inventories.

Explanation:
- `db.Inventories` represents the inventories table in the database which maps to a list of `Inventory` objects
- `.Include(inventory => inventory.Stock)` also initializes `Stock` property in the `Inventory` class.

  Without `.Include`, `Stock` property will be not initialized.

- `.ToList()` creates a list of `Inventory` objects which we can process, e.g., with a `foreach` loop


## Appendix

- <mslearn:ef/core/querying/related-data/eager> about including data to be loaded