Recap
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
https://dotnetintellect.com/2020/06/29/azure-cosmos-db-intro/
Azure Cosmos DB CLI
Let’s begin with creating Azure resources using CLI
//login
az login
//Resource group creation
$resourcegroup="CosmosDBverify"
az group create -l southindia -n $resourcegroup
//Cosmos DB Account creation
$name="cosmosverify"
az cosmosdb create -n $name -g $resourcegroup --default-consistency-level Session
//Cosmosdb creation
az cosmosdb sql database create -a $name -n $name -g $resourcegroup --throughput 400
Firstly, after running az login, CLI will open your default browser and load an Azure sign-in page. Thereafter, the user has to sign-in.
In the second part, we are creating resource group with the name “CosmosDBVerify” by running the below script
//Resource group creation
$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 by using
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. 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 utilise 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 create an entity classes
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 Separation of Concerns principle and couples persistence layer with domain model logic.
- Fluent API decouples my models from Entity Framework.
- It provides more options of 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 to implement 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 like the article. In case, you find the article interesting then kindly like and share it.
Pingback: Azure Cosmos DB-SQL API Geo Replication using EF Core- Part Three – Articles on latest .net technology
Pingback: Query and Mutation in GraphQL- Part two – Articles on latest .net technology