Introduction
In my previous article, we have seen the introduction of the Cosmos DB. If you haven’t read my previous article, then I highly encourage you to do so
here.
Azure Cosmos DB CLI
Let’s begin with creating Azure resources using CLI
-
- az login
-
-
- $resourcegroup="CosmosDBverify"
- az group create -l southindia -n $resourcegroup
-
-
- $name="cosmosverify"
- az cosmosdb create -n $name -g $resourcegroup --default-consistency-level Session
-
-
- az cosmosdb sql database create -a $name -n $name -g $resourcegroup --throughput 400
First, after running AZ login, CLI will open your default browser and load an Azure sign-in page. Afterward, the user has to sign-in.
In the second part, we are creating a resource group with the name “CosmosDBVerify” by running the below script:
- $resourcegroup="CosmosDBverify"
- az group create -l southindia -n $resourcegroup
Next, we are creating the Cosmos DB account by using the below script:
- $name="cosmosverify"
- az cosmosdb create -n $name -g $resourcegroup --default-consistency-level Session
Lastly, we are creating SQL Cosmos DB using the following:
- az cosmosdb sql database create -a $name -n $name -g $resourcegroup --throughput 400
Here, I want to be more specific about throughput, so setting it to 400 RU. The default value of throughput is 400 RU.
Note
As of today(July 5th, 2020), Microsoft is providing free Cosmos DB account for preview. You can utilize that as well by going directly
here.
Coding
In this article, I’m using a classic example of maintaining a user/employee profile such as information about his current company, previous companies, etc.
Without wasting much time, let’s begin by creating a .net core console application. Firstly, add Microsoft.EntityFrameworkCore.Cosmos NuGet package.
Let's create an entity class:
- public class Profile
- {
- public string Title { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public string DOB { get; set; }
- public string PhoneNumber { get; set; }
- public string Designation { get; set; }
- public Company CurrentCompany { get; set; }
- public string HighestEducation { get; set; }
- public ICollection<Company> PreviousCompanies { get; set; }
- public string UserId { get; set; }
- }
- public class Company
- {
- public string CompanyName { get; set; }
- public DateTime StartDate { get; set; }
- public DateTime EndDate { get; set; }
- public bool IsActive { get; set; }
- }
Instead of using Data Annotations, I would like to use Fluent API for certain reasons:
- Data Annotation violates the Separation of the Concerns principle and the couple's persistence layer with domain model logic.
- Fluent API decouples my models from Entity Framework.
- It provides more options for configurations than Data Annotation attributes.
Now, we can configure the mappings between these two entities by using IEntityTypeConfiguration<T> interface as follows:
- public class ProfileEntityConfiguration:IEntityTypeConfiguration<Profile>
- {
- public void Configure(EntityTypeBuilder<Profile> builder)
- {
- builder.HasKey(x => x.UserId);
- builder.HasPartitionKey(x => x.UserId);
- builder.OwnsOne(x => x.CurrentCompany);
- builder.OwnsMany(x => x.PreviousCompanies);
-
- }
- }
Methods |
Description |
HasKey |
It is used to denote the property that uniquely identifies an entity. This is mainly the Primary key of the table. |
HasPartitionKey |
It is used to store the partition key. In my example, I have used UserId as the partition key |
OwnsOne |
It is used to define one-one mapping between tables. |
OwnsMany |
It is used to define one-many mappings between tables |
After creating that class with the necessary customizations, you need to wire that up to your DbContext’s OnModelCreating method by calling modelBuilder.ApplyConfiguration(new ConfigClass()).
- public class ProfileContext:DbContext
- {
- public DbSet<Profile> Profiles { get; set; }
-
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- var accountEndpoint = "";
- var accountKey = "";
- var dbName = "";
- optionsBuilder.UseCosmos(accountEndpoint, accountKey, dbName);
- }
-
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.ApplyConfiguration(new ProfileEntityConfiguration());
- }
- }
Now writing our required logic in the main method:
- static void Main(string[] args)
- {
- var context = new ProfileContext();
- context.Database.EnsureCreated();
- context.Profiles.Add(new Profile
- {
- UserId = Guid.NewGuid().ToString(),
- CurrentCompany = new Company
- {
- CompanyName = "Infosys",
- StartDate = DateTime.Today,
- IsActive = true
- },
- PreviousCompanies=new List<Company>
- {
- new Company
- {
- CompanyName="Wipro",
- StartDate=DateTime.Today.AddYears(-7),
- IsActive=false
- }
- }
- });
- context.SaveChanges();
- Console.ReadLine();
- }
To keep it simple, I have directly used DbContext in the main program, but I would highly recommend you implement a repository pattern.
Note
Ef Core doesn’t support migration for Cosmos DB. In the above main function, I have used context.Database.EnsureCreated() to ensure whether the Cosmos DB is in sync with the entity classes.
In the next article, we’ll look into Geo-replication by using this example in the .NET core API.
I hope you liked the article. In case you found the article interesting, then kindly like and share it.