Quick start: ASP.Net Core 3.1 Entity Framework Core CQRS React JS Series part 1: db config code first

Ali Süleyman TOPUZ
C# Programming
Published in
3 min readDec 28, 2020

The parent content of this series: Quick start: ASP.Net Core 3.1, Entity Framework Core, CQRS, React JS Series

We don’t have a complex DB model for this application. Keep it simple! it is just to see how are things on the related topics.

Data structure in sentences

  • Tag is for keeping the tag information
  • Product is for keeping the product information
  • ProductsTags is for mapping table
namespace Domain
{
[Table("Tag")]
public class Tag
{
public Tag()
{
ProductsTags = new List<ProductsTags>();
}
public Guid Id { get; set; }


[Required(ErrorMessage = "Name is required")]
[StringLength(60, ErrorMessage = "Name can't be longer than 60 characters")]
public string Name { get; set; }

public ICollection<ProductsTags> ProductsTags { get; set; }
}

[Table("ProductsTags")]
public class ProductsTags
{
public Guid Id { get; set; }

public Guid ProductId { get; set; }
public Product Product { get; set; }

public Guid TagId { get; set; }
public Tag Tag { get; set; }
}

[Table("Product")]
public class Product
{
public Product()
{
ProductsTags = new List<ProductsTags>();
}
public Guid Id { get; set; }

[Required(ErrorMessage = "Name is required")]
[StringLength(60, ErrorMessage = "Name can't be longer than 60 characters")]
public string Name { get; set; }

[Required(ErrorMessage = "Product register date is required")]
public DateTime ProductRegisterDate { get; set; }

[Required(ErrorMessage = "Unit price is required")]
public decimal UnitPrice { get; set; }

public ICollection<ProductsTags> ProductsTags { get; set; }

}
}

Repository Context

namespace Domain.Infrastructure.EF
{
public class RepositoryContext : DbContext
{
public RepositoryContext(DbContextOptions options)
: base(options)
{

}


public DbSet<Product> Products { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<ProductsTags> ProductsTags { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Tag>().HasKey(t => new { t.Id });
modelBuilder.Entity<Tag>().Property(u => u.Id).IsRequired();
modelBuilder.Entity<Tag>().Property(u => u.Name).IsRequired();
modelBuilder.Entity<Tag>().HasIndex(u => u.Name).IsUnique();
modelBuilder.Entity<Tag>().HasMany(u => u.ProductsTags).WithOne(x => x.Tag).HasForeignKey(x => x.TagId);

modelBuilder.Entity<Product>().HasKey(t => new { t.Id });
modelBuilder.Entity<Product>().Property(u => u.Id).IsRequired();
modelBuilder.Entity<Product>().Property(u => u.Name).IsRequired();
modelBuilder.Entity<Product>().Property(u => u.UnitPrice).IsRequired();
modelBuilder.Entity<Product>().Property(u => u.ProductRegisterDate).IsRequired();
modelBuilder.Entity<Product>().HasMany(u => u.ProductsTags).WithOne(x => x.Product).HasForeignKey(x => x.ProductId);

modelBuilder.Entity<ProductsTags>().Property(u => u.Id).IsRequired();
modelBuilder.Entity<ProductsTags>().Property(u => u.TagId).IsRequired();
modelBuilder.Entity<ProductsTags>().Property(u => u.ProductId).IsRequired();
modelBuilder.Entity<ProductsTags>().HasKey(t => new { t.Id });
modelBuilder.Entity<ProductsTags>().HasOne<Product>(sc => sc.Product).WithMany(s => s.ProductsTags).HasForeignKey(sc => sc.ProductId);
modelBuilder.Entity<ProductsTags>().HasOne<Tag>(sc => sc.Tag).WithMany(s => s.ProductsTags).HasForeignKey(sc => sc.TagId);

SeedData(modelBuilder);
}

private void SeedData(ModelBuilder modelBuilder)
{
var iphoneId = Guid.NewGuid();
var iphone = new Product()
{
Id = iphoneId,
Name = "IPhone X",
ProductRegisterDate = DateTime.UtcNow,
UnitPrice = 1000
};
modelBuilder.Entity<Product>().HasData(iphone);


var mobilePhoneId = Guid.NewGuid();
var mobilePhone = new Tag
{
Id = mobilePhoneId,
Name = "Mobile phone"
};
modelBuilder.Entity<Tag>().HasData(mobilePhone);

var mobilePhoneIphone = new ProductsTags { Id = Guid.NewGuid(), ProductId = iphoneId, TagId = mobilePhoneId };
modelBuilder.Entity<ProductsTags>().HasData(mobilePhoneIphone);
}
}
}

Service Extensions

Register the context as follows:

public static void ConfigureDbContext(this IServiceCollection services, IConfiguration config)
{
var connectionString = config["ConnectionStrings:sqlConnection"];
services.AddDbContext<RepositoryContext>(o => o.UseSqlite(connectionString));
}

Db Migration

dotnet ef migrations add initial-migration -p Domain.Infrastructure.EF/ -s API/
dotnet ef database update initial-migration -p Domain.Infrastructure.EF/ -s API/

Migration Result

Generated database

Conclusion

So, we have a definition of the data model here. In other parts, structure of the projects as logical seperation will be explained.

--

--

Ali Süleyman TOPUZ
C# Programming

Software Engineering and Development Professional. Writes about software development & tech. 📍🇹🇷