This commit is contained in:
DB Lee 2021-09-15 21:10:25 -07:00
Родитель e9bf6145a2
Коммит a477f78f88
54 изменённых файлов: 1179 добавлений и 632 удалений

Просмотреть файл

109
.gitignore поставляемый
Просмотреть файл

@ -23,6 +23,7 @@ mono_crash.*
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
@ -31,11 +32,6 @@ bld/
[Ll]og/
[Ll]ogs/
## Project Specific
.venv
__pycache__
.vscode
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
@ -66,6 +62,12 @@ project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
@ -142,6 +144,11 @@ _TeamCity*
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
@ -354,6 +361,94 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# ipynb checkpoint
**/*.ipynb_checkpoints/
# Fody - auto-generated XML schema
FodyWeavers.xsd
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# JetBrains Rider
.idea/
*.sln.iml
##
## Visual Studio Code
##
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

Просмотреть файл

@ -1,25 +1,26 @@
# How to use CosmosDB Helper Library
>You need to have Azure subscription and provisioned Cosmos DB (SQL API or Mongo).
>You need to have Azure subscription and provisioned Azure Cosmos DB (SQL API or MongoDB API).
>
>Let's start it with Cosmos DB with SQL API (You may easily shift it for Mongo API later)
>Let's start it with Azure Cosmos DB with SQL API first (You may easily shift it for Mongo API later)
<br/>
## Work with Cosmos DB SDK
## Work with SQL API (Azure Cosmos DB SDK)
### 0. Pre-requisites
- We need to prepare CosmosDB Azure resources before starting it.
I assume you have CosmosDB SQL API interface instance and CosmosDB Mongo API interface instance.
- We need to prepare Azure CosmosDB resource before starting it.
I assume you have Azure CosmosDB SQL API instance and CosmosDB Mongo API instance both.
If you don't have it, please prepare your CosmosDB resources. Here is the link [how to provision your Cosmos DB resources from Azure Portal](https://docs.microsoft.com/en-us/azure/cosmos-db/create-cosmosdb-resources-portal)
Please make sure which API are you working with.
<img src="./media/azure-cosmos-db-create-new-account-detail.png" width="40%"/>
- .NET Framework 5.0
The Cosmos DB Helper libraries are compile with .NET Framework 5.0
The Cosmos DB Helper libraries has been compiled with .NET Framework 5.0
Before starting it, you need to install .NET Framework 5.0 in your development environment.
If you don't have it, please install it from here - [.NET Framework 5.0 SDK Download](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer)
@ -33,32 +34,45 @@ You might get following error :
Unfortunately this link doesn't point .NET Framework version 5, only 4.8 now.
To download version 5, you can download it from here [https://dotnet.microsoft.com/download/visual-studio-sdks](https://dotnet.microsoft.com/download/visual-studio-sdks)
and I do recommend you upgrade your Visual Studio version up to 16.8.x.
and I do recommend you upgrade your Visual Studio version up to 16.8.x.
- VS Code
It's OK to start with Visual Studio 2019 but I'm going to start with VS Code in this hands on.
It's OK to start with Visual Studio 2019 but I'm going to start with VS Code in this hands on.
If you don't have it, you may download it from here - [Download VSCode](https://code.visualstudio.com/)
### 1. Create Project
Please make sure all of pre-requisites are all set.
Let's start hands on from now on!
Let's start hands on for now!
Create Console project from Console Window
```
Create Console project from Console Window
dotnet new console -n CosmosHandsOn --framework net5.0
```
<img src="./media/dotnet%20new%20console.png" width="70%">
After creating Console project name CosmosHandsOn, Switch the directory to newly created project.
```
cd CosmosHandsOn
```
### 2. Add Reference CosmosDB Helper
After switching the directory, add package Reference with Nuget installation
dotnet add package EAE.Solutions.CosmosDB.SQL --version 0.6.1
```
dotnet add package EAE.Solutions.CosmosDB.SQL --version 0.7.0
```
<img src="./media/add%20reference.png" width="90%">
@ -67,20 +81,26 @@ After referencing CosmosDB Helper, let's define Entity Class will be stored in C
Open your VS Code with this command
```
code .
and add Entity Class name ToDo.cs
```
then Add Entity Class with name **ToDo.cs**
<img src="./media/add%20entity%20class.png" width="60%">
Define ToDo class with inheriting CosmosEntityBase in Microsoft.Solutions.CosmosDB namespace.
CosmosEntityBase class has responsibility for managing Entity's ID and PartitionKey which can impact to retrieving performance in the cosmos DB.
Define ToDo class with inheriting CosmosDBEntityBase in Microsoft.Solutions.CosmosDB Namespace.
CosmosDBEntityBase class has responsibility for managing Entity's ID and PartitionKey which may effect to retrieving performance in the cosmos DB.
```csharp
using System;
using Microsoft.Solutions.CosmosDB;
namespace CosmosHandsOn
{
public class ToDo : CosmosEntityBase
public class ToDo : CosmosDBEntityBase
{
public string title { get; set; }
public Status status { get; set; }
@ -109,20 +129,23 @@ CosmosEntityBase class has responsibility for managing Entity's ID and Partition
public enum Status { New, InProcess, Done }
}
```
### 4. Define Entity Collection Class
add new Entity Collection Service Class name ToDoService.cs
Now add new EntityCollectionBase Class with name **ToDoService.cs**
EntityCollectionBase class is managing Connection Objects and CRUD operations for CosmosDBEntityBase class objects
<img src="./media/add%20todoservice%20class.png" width="60%">
Define ToDoService class with inheriting SQLEntityCollectionBase and specify Entity Class types and it's identifier type.
The Entity class which inherited from CosmosEntityBase has a Guid string identifier.
Define ToDoService class with inheriting SQLEntityCollectionBase which is EntityCollectionBase class for SQL API and specify Entity Class types will manage.
Once you inherit SQLEntityCollectionBase class, you should generate constructor has 2 parameters which will be assigned as Database ConnectionString and Database Name.
<img src="./media/generate%20constructor.png" width="50%" />
Once you inherit SQLEntityCollectionBase class, you should generate constructor which has 2 parameters for Database ConnectionString and Database Name.
The 2 constructor parameters supposed to be passed to SQLEntityCollectionBase class for managing Azure CosmosDB connection and Entity object collection(container).
```csharp
using System;
using Microsoft.Solutions.CosmosDB.SQL;
@ -135,63 +158,92 @@ Once you inherit SQLEntityCollectionBase class, you should generate constructor
}
}
}
```
SQLEntityCollectionBase class provides features for CosmosDB CRUD operations with SQL API interface.
<img src="./media/generate%20constructor.png" width="50%" />
SQLEntityCollectionBase class provides features for Azure CosmosDB SQL API CRUD operations internally.
Let's define CRUD operations in ToDoService.
SQLEntityCollectionBase Class has EntityCollection property.
You can operate(Crate, Replace, Update, Delete) CosmosDB with your own Entities with this EntityCollection property.
You can operate(Crate, Replace, Update, Delete) Azure CosmosDB with your own Business Entities with it.
Below is the CRUD operations you may easily interact with Azure CosmosDB
- AddAsync method in EntityCollection can insert your object in CosmosDB
```csharp
public async Task<ToDo> Create(ToDo todo)
{
return await this.EntityCollection.AddAsync(todo);
}
```
- SaveAsync method in EntityCollection can update your object in CosmosDB.
```csharp
public async Task<ToDo> Update(ToDo todo)
{
return await this.EntityCollection.SaveAsync(todo);
}
```
- Get method in EntityCollection can retrieve Entity with Entity's id.(The Entity's identifier which will be managing by CosmosDB Helper class)
```csharp
- Get method in EntityCollection can retrieve Entity with Entity's id.(The Entitiy's identifier which will be managing by CosmosDB Helper class)
public async Task<ToDo> Find(string id)
{
return await this.EntityCollection.GetAsync(id);
}
```
- FindAllAsync method in EntityCollection can retrieve Entities with Linq statements.
- FindAllAsync method in EntityCollection can retrieve Entities with LINQ statements.
```csharp
public async Task<IEnumerable<ToDo>> Search(string notes)
{
return await this.EntityCollection.FindAllAsync(new GenericSpecification<ToDo>(x => x.notes.Contains(notes)));
}
```
- DeleteAsync method in EntityCollection can delete Entity by Entity's id or Entity itself.
```csharp
public async Task Delete(string id)
{
await this.EntityCollection.DeleteAsync(id);
}
```
Done! You are ready to create, update, search and delete Entities with these simple methods.
This is full ToDoServices.cs codes
```csharp
using System;
using Microsoft.Solutions.CosmosDB.SQL;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Solutions.CosmosDB;
using Microsoft.Solutions.CosmosDB.SQL;
namespace CosmosHandsOn{
public class ToDoService : SQLEntityCollectionBase<ToDo>
{
public ToDoService(string DataConnectionString, string CollectionName) : base(DataConnectionString, CollectionName)
{
//just passing constructor parameters
}
public async Task<ToDo> Create(ToDo todo)
@ -220,15 +272,19 @@ This is full ToDoServices.cs codes
}
}
}
```
Now you may put this ToDoService on wherever you want to host it through MicroService containers or Azure Functions.
Let's try to test it with Console Application from here.
Open Programs.cs and define CosmosDB ConnectionString.
Open **Programs.cs** and define CosmosDB ConnectionString.
To invoking asynchronous methods we need to change **static void Main** method signature to **async static Task Main** .
Please check you CosmosDB's connection string from Azure portal and paste it like below.
Please check your Azure CosmosDB connection string from Azure portal and copy & paste it like below.
```csharp
using System;
using System.Threading.Tasks;
@ -244,20 +300,30 @@ Please check you CosmosDB's connection string from Azure portal and paste it lik
}
}
}
```
And instancing ToDoService with connection string and Database name together.
And instantiate ToDoService with connection string and Database name together.
The SQLEntityCollectionBase which has been inherited by ToDoService is going to check existence of Database and once it is not exiting, it will generate Database automatically on the fly.
put this code for instancing ToDoService like below
Put this code for instancing ToDoService like below
```csharp
async static Task Main(string[] args)
{
var todoService = new ToDoService(connectionString, "CosmosHandson");
}
It will create Database name "CosmosHandson"
```
It will create CosmosHandson Database in your Azure CosmosDB.
Now add the codes for testing ToDoService with this codes
Create ToDo object like below.
```csharp
var todo = new ToDo()
{
@ -268,11 +334,15 @@ Create ToDo object like below.
notes = "Cosmos DB is really cool!",
status = Status.New
};
```
You might be acknowledged that ToDo class has id and __partitionkey properties.
You don't necessary to touch them from your code. the id and _partitionkey will be managed by CosmosDB Helper.
You might be acknowledged that ToDo class has id and __partitionkey properties natively.
You don't necessary to touch them from your code. the id and _partitionkey will be managed by CosmosDB Helper by itself.
After instancing ToDo class let's add the codes consequently.
After instancing ToDo class let's add the codes following.
```csharp
using System;
using System.Threading.Tasks;
@ -281,7 +351,7 @@ After instancing ToDo class let's add the codes consequently.
{
class Program
{
static string connectionString = "{Put your connectionstring};
static string connectionString = "{Put your connectionstring}";
async static Task Main(string[] args)
{
@ -321,78 +391,15 @@ After instancing ToDo class let's add the codes consequently.
}
}
}
```
and Execute the code with pressing F5(Debugging) or CTRL + F5(Execute without Debugging)
You may check every CRUD operation is working perfectly.
You may check every CRUD operations are working perfectly.
You are using CosmosDB SDK for SQL API library internally.
If someone wants to use CosmosDB with EntityFramework library, you may easily shift your code for EntityFramework with changing tiny codes.
<br/><br/>
---
<br/>
## Work with Cosmos DB with EntityFramework library
### 1. Add Reference
Back to the directory of your project file and add reference CosmosDB Helper for EFCore Library with Nuget package installation
dotnet add package EAE.Solutions.CosmosDB.EFCore --version 0.6.1
<img src="./media/switch%20directory%20add%20package.png" width="90%"/>
### 2. Inherit EFCoreEntityCollectionBase in ToDoService
Open the VS Code again from the source folder.
code .
In previous code, ToDoService inherited SQLEntityCollectionBase.
Just change its base class with **EFCoreEntityCollectionBase** updating using Microsoft.Solutions.CosmosDB.SQL namespace to **Microsoft.Solutions.CosmosDB.EFCore**.
using System;
using Microsoft.Solutions.CosmosDB.EFCore;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Solutions.CosmosDB;
namespace CosmosHandsOn{
public class ToDoService : EFCoreEntityCollectionBase<ToDo>
{
public ToDoService(string DataConnectionString, string CollectionName) : base(DataConnectionString, CollectionName)
{
}
public async Task<ToDo> Create(ToDo todo)
{
return await this.EntityCollection.AddAsync(todo);
}
public async Task<ToDo> Update(ToDo todo)
{
return await this.EntityCollection.SaveAsync(todo);
}
public async Task<ToDo> Find(string id)
{
return await this.EntityCollection.GetAsync(id);
}
public async Task<IEnumerable<ToDo>> Search(string notes)
{
return await this.EntityCollection.FindAllAsync(new GenericSpecification<ToDo>(x => x.notes.Contains(notes)));
}
public async Task Delete(string id)
{
await this.EntityCollection.DeleteAsync(id);
}
}
}
That's it! Execute the code with pressing F5(Debugging) or CTRL + F5(Execute without Debugging)
You may check your development experiences will be same whatever you are using CosmosDB SDK or EntityFramework.
it's time to use CosmosDB Mongo API Service with our code.
It's time to use Azure CosmosDB Mongo API Service with our code.
<br/><br/>
@ -400,21 +407,26 @@ it's time to use CosmosDB Mongo API Service with our code.
<br/><br/>
## Work with Cosmos DB for Mongo API
>It's easy!. Cosmos DBHelper provides exactly same development experience with previous one what we did.
>It's easy! We've already implemented all CRUD operations in ToDoService class.
Azure Cosmos DBHelper provides exactly same development experience with previous one what we did.
>
>To start with CosmosDB for Mongo API, you need to provision CosmosDB for Mongo API first.
>To start with Azure CosmosDB for Mongo API, You need to prepare Azure CosmosDB for Mongo API instance.
If You don't have it yet, deploy Azure CosmosDB for MongoDB like blow before moving further.
>
><img src="./media/provision%20cosmosdb%20mongo.png" width="60%">
>
>After provisioning CosmosDB for Mongo API, grep the connection string.
>The Connection for Mongo is different with CosmosDB for SQL API.
>After provisioning Azure CosmosDB for Mongo API, grep the connection string.
>The Connection string format for Mongo is different with Azure CosmosDB for SQL API.
### 1. Add Reference
Add CosmosDB mongo Helper library with nuget package reference in your source directory like below
Try to Add Azure CosmosDB mongo Helper library with nuget package reference in your source directory like below
dotnet add package EAE.Solutions.CosmosDB.Mongo --version 0.6.1
```
dotnet add package EAE.Solutions.CosmosDB.Mongo --version 0.7.0
```
<img src="./media/switch%20directory%20add%20package2.png" width="90%">
@ -422,11 +434,16 @@ Add CosmosDB mongo Helper library with nuget package reference in your source di
### 2. Inherit MongoEntityCollectionBase in ToDoService
Open the VS Code again from the source folder.
```
code .
In previous code, ToDoService inherited EFCoreEntityCollectionBase.
Just change its base class with **MongoEntityCollectionBase** updating using Microsoft.Solutions.CosmosDB.EFCore namespace to **Microsoft.Solutions.CosmosDB.Mongo**.
```
In previous code, ToDoService inherited SQLEntityCollectionBase.
Just replace ToDoService's base class with **MongoEntityCollectionBase** and replace **using Microsoft.Solutions.CosmosDB.SQL** namespace to **Microsoft.Solutions.CosmosDB.Mongo**.
```csharp
using System;
using Microsoft.Solutions.CosmosDB.Mongo;
using System.Threading.Tasks;
@ -467,9 +484,10 @@ Just change its base class with **MongoEntityCollectionBase** updating using Mic
}
}
```
### 3. Update ConnectionString
> Don't forget to update your connection string for Mongo in programs.cs file!
> Don't forget to update your connection string for MongoDB in programs.cs file!
That's all we should do to switch our code for using CosmosDB Mongo API.
Just Execute the code with pressing F5(Debugging) or CTRL + F5(Execute without Debugging)
@ -479,6 +497,8 @@ Just Execute the code with pressing F5(Debugging) or CTRL + F5(Execute without D
All of CosmosDB Helper is sharing [IDataRepositoryProvider](./src/Libraries/Microsoft.CosmosDB/../Microsoft.Solutions.CosmosDB/IDataRepositoryProvider.cs) interface.
```csharp
namespace Microsoft.Solutions.CosmosDB
{
public interface IDataRepositoryProvider<TEntity>
@ -486,14 +506,20 @@ All of CosmosDB Helper is sharing [IDataRepositoryProvider](./src/Libraries/Micr
IRepository<TEntity, TIdentifier> EntityCollection { get; init ; }
}
}
```
so you may inject your dependency with this interface.
This is the sample code snippet for showing how to inject dependency into DoToService.
services.AddTransient<IDataRepositoryProvider<ToDo>, TODOService>(x => { return new TODOService(configuration["ConnectionString"], "CosmosHandson"); });
```csharp
You may check the DOTO ASP.net API sample project from [here](../../tree/main/src/Sample/Microsoft.Solutions.CosmosDB.WebHost)
services.AddTransient<IDataRepositoryProvider<ToDo>, TODOService>(x => { return new TODOService(configuration["ConnectionString"], "CosmosHandson"); });
```
You may check the ToDo ASP.net API sample project from [here](../../tree/main/src/Sample/Microsoft.Solutions.CosmosDB.WebHost)
## Working in Visual Studio 2019 or 2017
Absolutely Visual Studio is the first citizen .NET Development.
@ -501,5 +527,323 @@ If you want to start hands on from .NET Framework, you may reference proper pack
<img src="./media/nuget%20package%20manager.png" width="60%" />
The CosmosDB Helper library is pre-lease version. at this moment.
Don't forget check **include prelease** box when you are retrieving packages.
## EAE.Solutions.CosmosDB.SQL.ChangeFeed - Change feed Processor Helper
> Currently it supports **SQL Core API only**, EAE.Solutions.CosmosDB.MongoDB.ChangeFeed will be released next version.
The change feed processor is part of the Azure Cosmos DB SDK V3.
**Watcher** class in Microsoft.Solutions.CosmosDB.SQL.ChangeFeed namespace derived from BackgroundService, which supports hosting and managing Change feed processors as well as handle change entity collections.
Just Passing monitored entity collections(container) name as parameter to Watcher class then you can catch the changed entity sets.
We can host Watcher on .NET Generic Host in ASP.net core - https://docs.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice
See the Sample Application for Azure CosmosDB Change feed host [here](./Sample/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service)
```csharp
using Microsoft.Extensions.Configuration;
using Microsoft.Solutions.CosmosDB.SQL.ChangeFeed;
using Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Solutions.CosmosDB.SQL.TODO.ChangeFeed.Service
{
public class Worker : Watcher<ToDo>
{
/// <summary>
/// Passing configuration by ASPnet core Dependency Injection
/// This Application sample shows how to detact changes for TODO collection by Microsoft.Solutions.CosmosDB.SQL.TODO.WebHost Demo App
/// </summary>
/// <param name="configuration">Check appsettings.json file definition</param>
public Worker(IConfiguration configuration) : base(configuration["Values:DBConnectionString"],
configuration["Values:MonitoredDatabaseName"],
configuration["Values:MonitoredContainerName"])
{
}
protected override Task OnChangedFeedDataSets(IReadOnlyCollection<ToDo> changes, CancellationToken cancellationToken)
{
//put your business logics with changes
foreach (var item in changes)
{
Console.WriteLine($"Detected operation for item with id {item.id} => {JsonConvert.SerializeObject(item)}");
}
return base.OnChangedFeedDataSets(changes, cancellationToken);
}
}
}
```
Now, Let's make our hands dirt by creating Change Feed Process Host for DoTo Entity Container what we tested in previous handson with Watcher class.
### 1. Create Project
Create Worker Service project from Console Window.
dotnet CLI tool provides [Worker Service host project template](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new-sdk-templates#web-others).
Type dotnet CLI command like below in your Console.
```
dotnet new worker -n CosmosHandsOnChangeFeed --framework net5.0
```
<img src="./media/dotnet new worker.png" width="80%" />
After creating project template, move the directory path to CosmosHandsOnChangeFeed
```
cd .\CosmosHandsOnChangeFeed
```
### 2. Add Reference CosmosDB Helper
After switching the directory, add package Reference with Nuget installation.
This Nuget package contains Watcher class in Microsoft.Solutions.CosmosDB.SQL.ChangeFeed Namespace
```
dotnet add package EAE.Solutions.CosmosDB.SQL.ChangeFeed --version 0.7.0
```
<img src="./media/add reference changefeed.png" width="90%">
Then Open VSCode
```
code .
```
You may check the .NET Generic Host ASP.net core project scarffolding source files.
<img src="./media/worker project.png" width="90%">
### 3. Add ToDo Entity class
Now we are going to add Entity Class where Monitored Container has.
We are going to watch ToDos Container what we created in previous handson.
Add new file with ToDo.cs and Copy below code and paste to ToDo.cs file
```csharp
using System;
using Microsoft.Solutions.CosmosDB;
namespace CosmosHandsOnChangeFeed
{
public class ToDo : CosmosDBEntityBase
{
public string title { get; set; }
public Status status { get; set; }
public DateTime startDate { get; set; }
public DateTime endDate { get; set; }
public string notes { get; set; }
private int _percentComplete;
public int percentComplete
{
get { return _percentComplete; }
set
{
if ((percentComplete < 0) || (percentComplete > 100))
{
throw new OverflowException("percent value should be between 0 to 100");
}
else
{
_percentComplete = percentComplete;
}
}
}
}
public enum Status { New, InProcess, Done }
}
```
### 4. Inherit Watcher Class in EAE.Solutions.CosmosDB.SQL.ChangeFeed
We have prepared ToDo EntityClass for monitoring entity container.
Now let's set up Watcher class to minitoring ToDos container.
Open Worker.cs file
``` csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace CosmosHandsOnChangeFeed
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
}
```
There are some sample codes for BackgroundService.
Add ```Microsoft.Solutions.CosmosDB.SQL.ChangeFeed``` Namespace and then change its Base Class from ```BackgroundService``` to ```Watcher<ToDo>```.
Then remove whole codes in Worker class like below.
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Solutions.CosmosDB.SQL.ChangeFeed;
namespace CosmosHandsOnChangeFeed
{
public class Worker : Watcher<ToDo>
{
}
}
```
Now Add Constructor with IConfiguration Dependency Injection and Pass 3 parameter to its Base class like below.
the 3 parameters supposed to be passed to Base class is Azure CosmosDB Connectionstring and Monitored Database and Container name.
We are going to update parameter information in appsettings.json file.
ASPnet core has its native Dependency Injection framework and it will read appsettings.json file then pass to every hosted instances at its constructor.
```csharp
public class Worker : Watcher<ToDo>
{
public Worker(IConfiguration configuration ) : base(configuration["Values:DBConnectionString"],
configuration["Values:MonitoredDatabaseName"],
configuration["Values:MonitoredContainerName"])
{
}
}
```
### 5. Override OnChangeFeedDataSets
Now Override ```OnChangeFeedDataSets``` from its Base class like below
<img src="./media/override OnChangeFeedDataSets.png" width="90%">
```csharp
protected override Task OnChangedFeedDataSets(IReadOnlyCollection<ToDo> changes, CancellationToken cancellationToken)
{
return base.OnChangedFeedDataSets(changes, cancellationToken);
}
```
Whenever Monitored Entity Container updated, The Watcher will catch them with ``IReadOnlyCollection<ToDo>`` changes parameter.
Just add the code for Printing out changes into Console window like below:
```csharp
protected override Task OnChangedFeedDataSets(IReadOnlyCollection<ToDo> changes, CancellationToken cancellationToken)
{
foreach (var item in changes)
{
Console.WriteLine($"Changed ToDo => Title : {item.title} /n Status : {item.status} / Notes : {item.notes} ");
}
return base.OnChangedFeedDataSets(changes, cancellationToken);
}
```
You can add your own business logics in here instead of Console print out at your requirements.
Here is the whole Worker.cs codes :
```csharp
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Solutions.CosmosDB.SQL.ChangeFeed;
namespace CosmosHandsOnChangeFeed
{
public class Worker : Watcher<ToDo>
{
public Worker(IConfiguration configuration ) : base(configuration["Values:DBConnectionString"],
configuration["Values:MonitoredDatabaseName"],
configuration["Values:MonitoredContainerName"])
{
}
protected override Task OnChangedFeedDataSets(IReadOnlyCollection<ToDo> changes, CancellationToken cancellationToken)
{
foreach (var item in changes)
{
Console.WriteLine($"Changed ToDo => Title : {item.title} /n Status : {item.status} / Notes : {item.notes} ");
}
return base.OnChangedFeedDataSets(changes, cancellationToken);
}
}
}
```
### 6. Update Configuration for ConnectionString and Monitored Entity Container Information
Open appsettings.json file and add configuration information like below :
```json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Values" : {
"DBConnectionString" : "{Put Your Connectionstring}",
"MonitoredDatabaseName" : "CosmosHandson",
"MonitoredContainerName" : "ToDos"
}
}
```
Now you are all set.
Whenerver ToDos entity container has been changed, you can catch them with this Worker class.
You may put it on Container and scale with Kubernetes clusters.

Просмотреть файл

@ -1,9 +1,37 @@
# CosmosDB Solution Accelerator for Developers (CosmosDB Helper Library)
# Azure CosmosDB Solution Accelerator for Developers <br/>(Azure CosmosDB Helper Library)
## About this repository
This Repository contains CosmosDB Helper Library source code and descriptions how to use it.
These resources help Developers quickly build applications with cosmosDB on Azure.
Welcome to Azure CosmosDB Solution Accelerator (Azure CosmosDB Helper).
Azure CosmosDB Helper supports MongoDB API and SQL Core API interface with LINQ statements.
Developers can their Business Entities CRUD Operations without learning specific query languages for each APIs.
Once your business logic has been built with LINQ statements with Azure CosmosDB Helper, you may easily switch two APIs with very few code changes.
This Repository contains Azure CosmosDB Helper Library source code and Hands on descriptions for how to use it.
## Version History
- ### v 0.7 Update
- #### Change feed processor for Azure CosmosDB Core SQL API
- **Microsoft.Solutions.CosmosDB.SQL.ChangeFeed** (ChangeFeed Processor Helper) has been released
- Automatic lease container creation
- Multiple process host support for parallel execution in Microservice deployment
- Delegate process template for detecting ChangeSets.
- #### Improved performance with optimized Connection Object
- #### CosmosEntityBase Name has been changed to **CosmosDBEntityBase**
- Azure CosmosDB Core SQL API EF Core <span style="color:red">Deprecated</span>
- Azure CosmosDB Provider - EF Core wrapper has been deprecated
(EF Core Framework's performance issue)
- ### v 0.6 First Release
- #### Azure CosmosDB Core SQL API support
- Azure CosmosDB SDK wrapper
- Azure CosmosDB Provider - EF Core wrapper
- #### Azure CosmosDB MongoDB SQL API Support
- MongoDB.Driver wrapper
## Prerequisites
This source code has been built with .NET framework 5.0
(but you may build it with .NET Core 3.1 as well)
@ -12,7 +40,7 @@ This source code has been built with .NET framework 5.0
CosmosDB Solution Accelerator helps developers who wants to use CosmosDB with **SIMPLE** and **DEVELOPMENT CONSISTENCY**.
Developers can easily switch CosmosDB APIs between SQL API and Mongo API with little changes
## How to Use it
## How to Work with it
You may start with [HandsOn](./HandsOn.md) page.
All of libraries can be referenced though [Nuget packages](https://www.nuget.org/packages?q=EAE.Solutions) to your project.

Двоичные данные
media/Worker Generate Constructor.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 63 KiB

Двоичные данные
media/add reference changefeed.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 91 KiB

Двоичные данные
media/dotnet new worker.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 25 KiB

Двоичные данные
media/nuget package manager.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 64 KiB

После

Ширина:  |  Высота:  |  Размер: 64 KiB

Двоичные данные
media/override OnChangeFeedDataSets.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 137 KiB

Двоичные данные
media/worker project.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 110 KiB

Просмотреть файл

@ -1,107 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.Solutions.CosmosDB.EFCore
{
public delegate void EFOnModelCreating(ModelBuilder modelBuilder);
public class BusinessTransactionRepository<TEntity, TIdentifier> : DbContext,
IRepository<TEntity, TIdentifier> where TEntity : class, IEntityModel<string>
{
public event EFOnModelCreating OnEFModelCreating;
public DbSet<TEntity> CurrentEntity { get; set; }
private string connectionString = "";
private string databaseName = "";
public BusinessTransactionRepository(string ConnectionString, string DatabaseName)
{
connectionString = ConnectionString;
databaseName = DatabaseName;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseCosmos(connectionString, databaseName);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TEntity>().ToContainer(typeof(TEntity).Name + "s");
modelBuilder.Entity<TEntity>()
.HasPartitionKey("__partitionkey")
.HasKey(e => e.id);
OnEFModelCreating(modelBuilder);
base.OnModelCreating(modelBuilder);
}
public async Task<TEntity> GetAsync(TIdentifier id)
{
return await this.FindAsync<TEntity>(id);
}
public async Task<TEntity> AddAsync(TEntity entity)
{
this.CurrentEntity.Add(entity);
await this.SaveChangesAsync(true);
return entity;
}
public async Task<TEntity> FindAsync(ISpecification<TEntity> specification)
{
return await this.CurrentEntity.FirstOrDefaultAsync<TEntity>(specification.Predicate);
}
public async Task<IEnumerable<TEntity>> GetAllAsync()
{
return await CurrentEntity.Where<TEntity>(x => true).ToArrayAsync();
}
public async Task<IEnumerable<TEntity>> FindAllAsync(ISpecification<TEntity> specification)
{
return await CurrentEntity.Where<TEntity>(specification.Predicate).ToListAsync();
}
public async Task<IEnumerable<TEntity>> GetAllAsync(IEnumerable<TIdentifier> identifiers)
{
List<TEntity> results = new List<TEntity>();
foreach (var i in identifiers)
results.Add(await CurrentEntity.FindAsync(i));
return results;
}
public async Task<TEntity> SaveAsync(TEntity entity)
{
this.Update<TEntity>(entity);
var affected = await this.SaveChangesAsync();
return entity;
}
public async Task DeleteAsync(TIdentifier EntityId)
{
this.Remove<TEntity>(this.Find<TEntity>(EntityId));
await this.SaveChangesAsync(true);
}
public async Task DeleteAsync(TEntity entity)
{
this.Remove<TEntity>(entity);
await this.SaveChangesAsync(true);
}
}
}

Просмотреть файл

@ -1,40 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.EntityFrameworkCore;
namespace Microsoft.Solutions.CosmosDB.EFCore
{
public class EFCoreEntityCollectionBase<TEntity> : IDataRepositoryProvider<TEntity>
where TEntity : class, IEntityModel<string>
{
public IRepository<TEntity, string> EntityCollection { get; init; }
private static bool ensured = false;
public EFCoreEntityCollectionBase(string DataConnectionString, string CollectionName)
{
var dbContext = new BusinessTransactionRepository<TEntity, string>(DataConnectionString,
CollectionName);
dbContext.OnEFModelCreating += DbContext_OnEFModelCreating;
if (!EFCoreEntityCollectionBase<TEntity>.ensured)
{
dbContext.Database.EnsureCreatedAsync().GetAwaiter().GetResult();
EFCoreEntityCollectionBase<TEntity>.ensured = true;
}
this.EntityCollection = dbContext;
}
private void DbContext_OnEFModelCreating(ModelBuilder modelBuilder)
{
ModelCreating(modelBuilder);
}
protected virtual void ModelCreating(ModelBuilder modelBuilder)
{
}
}
}

Просмотреть файл

@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Title>Microsoft CosmosDB Solution Accelerator - CosmosDB Helper for SQL(using EFCore5)</Title>
<PackageId>EAE.Solutions.CosmosDB.EFCore</PackageId>
<Version>0.6.1</Version>
<Authors>DB Lee</Authors>
<Company>Microsoft Coporation</Company>
<PackageDescription>This library helps using CosmosDB to developers...</PackageDescription>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Cosmos" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB\Microsoft.Solutions.CosmosDB.csproj">
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<IncludeAssets>Microsoft.Solutions.CosmosDB.dll</IncludeAssets>
</ProjectReference>
</ItemGroup>
<Target DependsOnTargets="ResolveReferences" Name="CopyProjectReferencesToPackage">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))"/>
</ItemGroup>
</Target>
</Project>

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 12 KiB

Просмотреть файл

@ -4,14 +4,15 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using MongoDB.Driver.Core;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace Microsoft.Solutions.CosmosDB.Mongo
{
public class BusinessTransactionRepository<TEntity, TIdentifier> : IRepository<TEntity, TIdentifier> where TEntity : class, IEntityModel<string>
public class BusinessTransactionRepository<TEntity, TIdentifier> : IRepository<TEntity, TIdentifier> where TEntity : class, IEntityModel<TIdentifier>
{
private readonly IMongoDatabase _database;
@ -39,15 +40,34 @@ namespace Microsoft.Solutions.CosmosDB.Mongo
public async Task<IEnumerable<TEntity>> FindAllAsync(FilterDefinition<TEntity> builders)
{
var collection = _database.GetCollection<TEntity>(typeof(TEntity).Name.ToLowerInvariant());
return (await collection.FindAsync(builders)).ToList<TEntity>();
}
public async Task<IEnumerable<TEntity>> FindAllAsync(ISpecification<TEntity> specification)
{
var collection = _database.GetCollection<TEntity>(typeof(TEntity).Name.ToLowerInvariant());
return (await collection.FindAsync(specification.Predicate)).ToList<TEntity>();
GenericSpecification<TEntity> genericSpecification = specification as GenericSpecification<TEntity>;
if (genericSpecification.OrderBy == null)
{
return (await collection.FindAsync(specification.Predicate)).ToList<TEntity>();
}
else if (genericSpecification.Order == Order.Asc)
{
return (await collection.FindAsync(specification.Predicate, new FindOptions<TEntity>() { Sort = Builders<TEntity>.Sort.Ascending(specification.OrderBy) })).ToList<TEntity>();
}
else if (genericSpecification.Order == Order.Desc)
{
return (await collection.FindAsync(specification.Predicate, new FindOptions<TEntity>() { Sort = Builders<TEntity>.Sort.Descending(specification.OrderBy) })).ToList<TEntity>();
}
else
{
return null;
}
}
@ -93,14 +113,14 @@ namespace Microsoft.Solutions.CosmosDB.Mongo
return entity;
}
public async Task DeleteAsync(TIdentifier entityId)
public async Task DeleteAsync(TIdentifier entityId, dynamic partitionKeyValue = null)
{
var collection = _database.GetCollection<TEntity>(typeof(TEntity).Name.ToLowerInvariant());
await collection.DeleteOneAsync(x => x.id.Equals(entityId));
}
public async Task DeleteAsync(TEntity entity)
public async Task DeleteAsync(TEntity entity, dynamic partitionKeyValue = null)
{
var collection = _database.GetCollection<TEntity>(typeof(TEntity).Name.ToLowerInvariant());

Просмотреть файл

@ -3,13 +3,14 @@
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Title>Microsoft CosmosDB Solution Accelerator - CosmosDB Helper for Mongo API</Title>
<PackageId>EAE.Solutions.CosmosDB.Mongo</PackageId>
<Version>0.6.1</Version>
<Authors>DB Lee</Authors>
<PackageId>EAE,Solutions.CosmosDB.Mongo</PackageId>
<Version>0.7.0</Version>
<Authors>Microsoft Solutions</Authors>
<Company>Microsoft Coporation</Company>
<PackageDescription>This library helps using CosmosDB to developers...</PackageDescription>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
<PackageProjectUrl>https://github.com/microsoft/CosmosDB-Solution-Accelerator-CosmosDB-Helper</PackageProjectUrl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@ -18,7 +19,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MongoDB.Driver" Version="2.11.5" />
<PackageReference Include="MongoDB.Driver" Version="2.13.1" />
</ItemGroup>
@ -30,7 +31,7 @@
</ItemGroup>
<Target DependsOnTargets="ResolveReferences" Name="CopyProjectReferencesToPackage">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths-&gt;WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the MIT License.
using MongoDB.Driver;
using System;
namespace Microsoft.Solutions.CosmosDB.Mongo
{
@ -12,9 +13,32 @@ namespace Microsoft.Solutions.CosmosDB.Mongo
public MongoEntntyCollectionBase(string DataConnectionString, string CollectionName)
{
CosmosMongoClientManager.DataconnectionString = DataConnectionString;
MongoClient _client = CosmosMongoClientManager.Instance;
this.EntityCollection =
new BusinessTransactionRepository<TEntity, string>(new MongoClient(DataConnectionString),
new BusinessTransactionRepository<TEntity, string>(_client,
CollectionName);
}
}
public sealed class CosmosMongoClientManager
{
private CosmosMongoClientManager() { }
static CosmosMongoClientManager()
{
}
public static string DataconnectionString;
private static readonly Lazy<MongoClient> _instance =
new Lazy<MongoClient>(() => new MongoClient(CosmosMongoClientManager.DataconnectionString));
public static MongoClient Instance
{
get { return _instance.Value; }
}
}
}

Просмотреть файл

@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Azure.Cosmos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Solutions.CosmosDB.SQL.ChangeFeed
{
public class ChangeFeedProcessHelper<TEntity>
{
public async Task<ChangeFeedProcessor> InitChangeFeedProcessorAsync(
string DataConnectionString,
string SourceDatabaseName,
string MonitoredContainerName,
Container.ChangesHandler<TEntity> ChangeHandler
)
{
Container leaseContainer;
Database database;
string leaseContainerName = $"{MonitoredContainerName}_lease";
var processorName = $"{MonitoredContainerName}_changefeedwatcher";
var instanceName = $"{processorName}_host_{Guid.NewGuid().ToString().Substring(0,8)}";
//Initialize CosmosDB Connection
CosmosClient cosmosClient = new CosmosClient(DataConnectionString);
database = cosmosClient.GetDatabase(SourceDatabaseName);
if (database is null) throw new NullReferenceException("Specified Database doesn't exist");
leaseContainer = await database.CreateContainerIfNotExistsAsync(leaseContainerName, "/partitionKey");
ChangeFeedProcessor changeFeedProcessor = database.GetContainer(MonitoredContainerName)
.GetChangeFeedProcessorBuilder<TEntity>(processorName: processorName, ChangeHandler)
.WithInstanceName(instanceName)
.WithLeaseContainer(leaseContainer)
.Build();
Console.WriteLine($"Starting Change Feed Processor...{processorName} in {instanceName}");
await changeFeedProcessor.StartAsync();
Console.WriteLine($"Change Feed Processor {processorName} started in {instanceName}");
return changeFeedProcessor;
}
}
}

Просмотреть файл

@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Title>Microsoft CosmosDB Solution Accelerator - CosmosDB Helper for SQL(using SDK)</Title>
<PackageId>EAE.Solutions.CosmosDB.SQL.ChangeFeed</PackageId>
<Version>0.7.0</Version>
<Authors>Microsoft Solutions</Authors>
<Company>Microsoft Coporation</Company>
<PackageDescription>This library helps using CosmosDB to developers...</PackageDescription>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
<PackageProjectUrl>https://github.com/microsoft/CosmosDB-Solution-Accelerator-CosmosDB-Helper</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.20.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB\Microsoft.Solutions.CosmosDB.csproj">
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<IncludeAssets>Microsoft.Solutions.CosmosDB.dll</IncludeAssets>
</ProjectReference>
</ItemGroup>
<Target DependsOnTargets="ResolveReferences" Name="CopyProjectReferencesToPackage">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths-&gt;WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Azure.Cosmos;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Solutions.CosmosDB.SQL;
namespace Microsoft.Solutions.CosmosDB.SQL.ChangeFeed
{
public class Watcher<TEntity> : BackgroundService
{
readonly string dataConnectionString;
readonly string sourceDatabaseName;
readonly string sourceContainerName;
private ChangeFeedProcessor changeFeedProcessor;
public Watcher(string ConnectionString, string MonitoredDatabaseName, string MonitoredContainerName)
{
dataConnectionString = ConnectionString;
sourceDatabaseName = MonitoredDatabaseName;
sourceContainerName = MonitoredContainerName;
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
ChangeFeedProcessHelper<TEntity> changeFeedWatcher = new ChangeFeedProcessHelper<TEntity>();
changeFeedProcessor = await changeFeedWatcher.InitChangeFeedProcessorAsync(dataConnectionString, sourceDatabaseName, sourceContainerName, HandleChangesAsync);
Console.WriteLine("Change feed watcher started");
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
await changeFeedProcessor.StopAsync();
Console.WriteLine("Change feed watcher stopped");
}
protected async Task HandleChangesAsync(IReadOnlyCollection<TEntity> changes, CancellationToken cancellationToken)
{
await OnChangedFeedDataSets(changes, cancellationToken);
}
protected virtual Task OnChangedFeedDataSets(IReadOnlyCollection<TEntity> changes, CancellationToken cancellationToken) {
return null;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(500, stoppingToken);
}
}
}
}

Просмотреть файл

@ -14,20 +14,28 @@ namespace Microsoft.Solutions.CosmosDB.SQL
{
private readonly Database _database;
private readonly Container _container;
private static bool ensured = false;
static bool _checkedDatabase = false;
public BusinessTransactionRepository(CosmosClient client, string DatabaseName)
public BusinessTransactionRepository(CosmosClient client, string DatabaseName, string containerName = "")
{
if (!BusinessTransactionRepository<TEntity, TIdentifier>.ensured)
if (!BusinessTransactionRepository<TEntity, TIdentifier>._checkedDatabase)
{
_database = client.CreateDatabaseIfNotExistsAsync(DatabaseName).Result;
_container = _database.CreateContainerIfNotExistsAsync(typeof(TEntity).Name + "s", "/__partitionkey").Result;
BusinessTransactionRepository<TEntity, TIdentifier>.ensured = true;
} else
BusinessTransactionRepository<TEntity, TIdentifier>._checkedDatabase = true;
}
else
{
_database = client.GetDatabase(DatabaseName);
_container = _database.GetContainer(typeof(TEntity).Name + "s");
}
if (string.IsNullOrEmpty(containerName))
{
_container = _database.CreateContainerIfNotExistsAsync(typeof(TEntity).Name + "s", "/__partitionkey").Result;
}
else
{
_container = _database.GetContainer(containerName);
}
}
@ -35,15 +43,16 @@ namespace Microsoft.Solutions.CosmosDB.SQL
public async Task<TEntity> GetAsync(TIdentifier id)
{
var iterator = this._container.GetItemQueryIterator<TEntity>($"select * from c where c.id = '{id.ToString()}'");
if (iterator.HasMoreResults)
{
return (await iterator.ReadNextAsync()).FirstOrDefault<TEntity>();
}
else
while (iterator.HasMoreResults)
{
return null;
foreach (var item in await iterator.ReadNextAsync())
{
return item;
}
}
return null;
}
public async Task<TEntity> AddAsync(TEntity entity)
@ -56,15 +65,15 @@ namespace Microsoft.Solutions.CosmosDB.SQL
{
var iterator = this._container.GetItemLinqQueryable<TEntity>().Where(specification.Predicate).ToFeedIterator();
if (iterator.HasMoreResults)
while (iterator.HasMoreResults)
{
return (await iterator.ReadNextAsync()).FirstOrDefault();
foreach (var item in await iterator.ReadNextAsync())
{
return item;
}
}
}
else
{
return null;
}
return null;
}
public async Task<IEnumerable<TEntity>> GetAllAsync()
@ -87,7 +96,25 @@ namespace Microsoft.Solutions.CosmosDB.SQL
public async Task<IEnumerable<TEntity>> FindAllAsync(ISpecification<TEntity> specification)
{
var iterator = this._container.GetItemLinqQueryable<TEntity>().Where(specification.Predicate).ToFeedIterator();
GenericSpecification<TEntity> genericSpecification = specification as GenericSpecification<TEntity>;
FeedIterator<TEntity> iterator = null;
if (genericSpecification.OrderBy == null)
{
iterator = this._container.GetItemLinqQueryable<TEntity>().Where(specification.Predicate).ToFeedIterator();
}
else
{
if (genericSpecification.Order == Order.Asc)
{
iterator = this._container.GetItemLinqQueryable<TEntity>().Where(specification.Predicate).OrderBy(specification.OrderBy).ToFeedIterator();
}
else
{
iterator = this._container.GetItemLinqQueryable<TEntity>().Where(specification.Predicate).OrderByDescending(specification.OrderBy).ToFeedIterator();
}
}
List<TEntity> results = new List<TEntity>();
@ -109,7 +136,7 @@ namespace Microsoft.Solutions.CosmosDB.SQL
foreach (var id in identifiers)
{
var iterator = this._container.GetItemLinqQueryable<TEntity>().Where(x => x.id.Equals(id)).ToFeedIterator();
var iterator = this._container.GetItemQueryIterator<TEntity>($"select * from c where c.id = '{id.ToString()}'");
while (iterator.HasMoreResults)
{
@ -132,17 +159,48 @@ namespace Microsoft.Solutions.CosmosDB.SQL
}
public async Task DeleteAsync(TIdentifier EntityId)
public async Task DeleteAsync(TIdentifier EntityId, dynamic partitionKeyValue = null)
{
var cosmosEntity = await this.GetAsync(EntityId) as CosmosEntityBase;
await this._container.DeleteItemAsync<TEntity>(EntityId.ToString(), new PartitionKey(cosmosEntity.__partitionkey) );
var cosmosEntity = await this.GetAsync(EntityId) as TEntity;
if (partitionKeyValue == null)
{
await this._container.DeleteItemAsync<TEntity>(cosmosEntity.id.ToString(), new PartitionKey(cosmosEntity.__partitionkey));
}
else
{
await this._container.DeleteItemAsync<TEntity>(cosmosEntity.id.ToString(), new PartitionKey(partitionKeyValue));
}
}
public async Task DeleteAsync(TEntity entity, dynamic partitionKeyValue = null)
{
var cosmosEntity = entity as CosmosDBEntityBase;
if (partitionKeyValue == null)
{
await this._container.DeleteItemAsync<TEntity>(entity.id.ToString(), new PartitionKey(cosmosEntity.__partitionkey));
}
else
{
await this._container.DeleteItemAsync<TEntity>(entity.id.ToString(), new PartitionKey(partitionKeyValue));
}
}
public async Task DeleteAsync(TEntity entity)
public async Task<TEntity> Find(ISpecification<TEntity> specification)
{
var cosmosEntity = entity as CosmosEntityBase;
await this._container.DeleteItemAsync<TEntity>(entity.id.ToString(), new PartitionKey(cosmosEntity.__partitionkey));
var iterator = this._container.GetItemLinqQueryable<TEntity>().Where(specification.Predicate).ToFeedIterator();
while (iterator.HasMoreResults)
{
foreach (var item in await iterator.ReadNextAsync())
{
return item;
}
}
return null;
}
}
}

Просмотреть файл

@ -4,12 +4,13 @@
<TargetFramework>net5.0</TargetFramework>
<Title>Microsoft CosmosDB Solution Accelerator - CosmosDB Helper for SQL(using SDK)</Title>
<PackageId>EAE.Solutions.CosmosDB.SQL</PackageId>
<Version>0.6.1</Version>
<Authors>DB Lee</Authors>
<Version>0.7.0</Version>
<Authors>Microsoft Solutions</Authors>
<Company>Microsoft Coporation</Company>
<PackageDescription>This library helps using CosmosDB to developers...</PackageDescription>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
<PackageProjectUrl>https://github.com/microsoft/CosmosDB-Solution-Accelerator-CosmosDB-Helper</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>
@ -24,7 +25,7 @@
</ItemGroup>
<Target DependsOnTargets="ResolveReferences" Name="CopyProjectReferencesToPackage">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))"/>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths-&gt;WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>
</Project>

Просмотреть файл

@ -2,7 +2,8 @@
// Licensed under the MIT License.
using Microsoft.Azure.Cosmos;
using System;
using System.Diagnostics;
namespace Microsoft.Solutions.CosmosDB.SQL
{
@ -13,7 +14,8 @@ namespace Microsoft.Solutions.CosmosDB.SQL
public SQLEntityCollectionBase(string DataConnectionString, string CollectionName)
{
CosmosClient _client = new CosmosClient(DataConnectionString);
CosmosClientManager.DataconnectionString = DataConnectionString;
CosmosClient _client = CosmosClientManager.Instance;
this.EntityCollection =
new BusinessTransactionRepository<TEntity, string>(_client,
@ -21,4 +23,28 @@ namespace Microsoft.Solutions.CosmosDB.SQL
}
}
public sealed class CosmosClientManager
{
private CosmosClientManager() { }
static CosmosClientManager()
{
//Type defaultTrace = Type.GetType("Microsoft.Azure.Cosmos.Core.Trace.DefaultTrace,Microsoft.Azure.Cosmos.Direct");
//TraceSource traceSource = (TraceSource)defaultTrace.GetProperty("TraceSource").GetValue(null);
//traceSource.Switch.Level = SourceLevels.Off;
//traceSource.Listeners.Clear();
}
public static string DataconnectionString;
private static readonly Lazy<CosmosClient> _instance =
new Lazy<CosmosClient>(() => new CosmosClient(CosmosClientManager.DataconnectionString));
public static CosmosClient Instance
{
get { return _instance.Value; }
}
}
}

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT License.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Solutions.CosmosDB.EFCore;
using System.Threading.Tasks;
using System.Linq;
using System;
@ -15,6 +14,7 @@ namespace Microsoft.Solutions.CosmosDB.Test
public class CosmosDBLibTest
{
public static IRepository<Person, string> repository = null;
private static string cosmossqlConn = "{PUT YOUR COSMOS SQL API CONNECTION STRING}";
private static string cosmosmongoConn = "{PUT YOUR COSMOS MONGO API CONNECTION STRING}";
@ -24,13 +24,12 @@ namespace Microsoft.Solutions.CosmosDB.Test
public void TestInit()
{
//Mongo Test
Repository = new MongoRepository(cosmosmongoConn, "MongoTEST");
//Repository = new MongoRepository(cosmosmongoConn, "MongoTEST");
//EF Test
//Repository = new CosmosEFRepository(cosmossqlConn, "EFTEST");
//SQL SDK Test
//Repository = new CosmosEFRepository(cosmossqlConn, "SDKTEST");
Repository = new CosmosSQLRepository(cosmossqlConn, "SDKTEST");
}
@ -87,6 +86,21 @@ namespace Microsoft.Solutions.CosmosDB.Test
System.Console.WriteLine($"{item.name} - {item.gender} - {item.title} - {item.age}");
}
Console.WriteLine($"Order by name ASC");
results = await repository.FindAllAsync(new GenericSpecification<Person>(x => x.age > 10, x => x.name, Order.Asc));
foreach (var item in results)
{
System.Console.WriteLine($"{item.name} - {item.gender} - {item.title} - {item.age}");
}
Console.WriteLine($"Order by name DESC");
results = await repository.FindAllAsync(new GenericSpecification<Person>(x => x.age > 10, x => x.name, Order.Desc));
foreach (var item in results)
{
System.Console.WriteLine($"{item.name} - {item.gender} - {item.title} - {item.age}");
}
Assert.AreNotSame(0, results.Count());
}
@ -117,7 +131,7 @@ namespace Microsoft.Solutions.CosmosDB.Test
await repository.DeleteAsync(_30agedperson);
Console.WriteLine($"{_30agedperson.id} object has been delete");
Console.WriteLine($"{_30agedperson.id} object has been deleted");
}
[TestMethod]
@ -128,7 +142,7 @@ namespace Microsoft.Solutions.CosmosDB.Test
await repository.DeleteAsync(_30agedperson.id);
Console.WriteLine($"{_30agedperson.id} object has been delete");
Console.WriteLine($"{_30agedperson.id} object has been deleted");
}
}
@ -140,14 +154,6 @@ namespace Microsoft.Solutions.CosmosDB.Test
}
}
public class CosmosEFRepository : EFCoreEntityCollectionBase<Person>
{
public CosmosEFRepository(string DataConnectionString, string CollectionName) : base(DataConnectionString, CollectionName)
{
CosmosDBLibTest.repository = this.EntityCollection;
}
}
public class CosmosSQLRepository : SQLEntityCollectionBase<Person>
{
public CosmosSQLRepository(string DataConnectionString, string CollectionName) : base(DataConnectionString, CollectionName)
@ -156,7 +162,7 @@ namespace Microsoft.Solutions.CosmosDB.Test
}
}
public class Person : CosmosEntityBase
public class Person : CosmosDBEntityBase
{
public string name { get; set; }
public int age { get; set; }

Просмотреть файл

@ -12,13 +12,15 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="coverlet.collector" Version="1.3.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="1.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB.EFCore\Microsoft.Solutions.CosmosDB.EFCore.csproj" />
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB.Mongo\Microsoft.Solutions.CosmosDB.Mongo.csproj" />
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB.SQL\Microsoft.Solutions.CosmosDB.SQL.csproj" />
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB\Microsoft.Solutions.CosmosDB.csproj" />

Просмотреть файл

@ -7,12 +7,12 @@ using System.Text;
namespace Microsoft.Solutions.CosmosDB
{
public class CosmosEntityBase : IEntityModel<string>
public class CosmosDBEntityBase : IEntityModel<string>
{
public CosmosEntityBase()
public CosmosDBEntityBase()
{
this.id = Guid.NewGuid().ToString();
this.__partitionkey = CosmosEntityBase.GetKey(id, 9999);
this.__partitionkey = CosmosDBEntityBase.GetKey(id, 9999);
}
/// <summary>
@ -27,7 +27,7 @@ namespace Microsoft.Solutions.CosmosDB
static SHA1 _sha1;
static CosmosEntityBase()
static CosmosDBEntityBase()
{
_sha1 = SHA1.Create();
}
@ -35,7 +35,7 @@ namespace Microsoft.Solutions.CosmosDB
/// <summary>
/// Generate partitionkey for CosmosDB
/// using SHA1 hash with id, convert it to uint and divide with number of partitions
/// assigned default value as 1000 (1000 partition at this moment)
/// assigned default value as 9999 (9999 partition at this moment)
/// </summary>
/// <param name="id"></param>
/// <param name="numberofPartitions"></param>

Просмотреть файл

@ -8,14 +8,23 @@ namespace Microsoft.Solutions.CosmosDB
{
public class GenericSpecification<TEntity> : ISpecification<TEntity>
{
public GenericSpecification(Expression<Func<TEntity, bool>> predicate)
public GenericSpecification(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, dynamic>> orderBy = null, Order order = Order.Asc)
{
Predicate = predicate;
OrderBy = orderBy;
Order = order;
}
/// <summary>
/// Gets or sets the func delegate query to execute against the repository for searching records.
/// </summary>
public Expression<Func<TEntity, bool>> Predicate { get; }
public Expression<Func<TEntity, dynamic>> OrderBy { get; }
public Order Order { get; }
}
public enum Order
{
Asc,
Desc
}
}

Просмотреть файл

@ -14,8 +14,8 @@ namespace Microsoft.Solutions.CosmosDB
public interface IRepository<TEntity, TIdentifier>
{
Task<TEntity> AddAsync(TEntity entity);
Task DeleteAsync(TEntity entity);
Task DeleteAsync(TIdentifier entityId);
Task DeleteAsync(TEntity entit, dynamic partitionKeyValue = null);
Task DeleteAsync(TIdentifier entityId, dynamic partitionKeyValue = null);
Task<TEntity> FindAsync(ISpecification<TEntity> specification);
Task<IEnumerable<TEntity>> FindAllAsync(ISpecification<TEntity> specification);
Task<TEntity> GetAsync(TIdentifier id);

Просмотреть файл

@ -12,5 +12,6 @@ namespace Microsoft.Solutions.CosmosDB
/// Gets or sets the func delegate query to execute against the repository for searching records.
/// </summary>
Expression<Func<TEntity, bool>> Predicate { get; }
Expression<Func<TEntity, dynamic>> OrderBy { get; }
}
}

Просмотреть файл

@ -2,6 +2,8 @@
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PackageProjectUrl>https://github.com/microsoft/CosmosDB-Solution-Accelerator-CosmosDB-Helper</PackageProjectUrl>
<PackageId>EAE.Solutions.CosmosDB</PackageId>
</PropertyGroup>
</Project>

Просмотреть файл

@ -3,10 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30711.63
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.Mongo", "libraries\Microsoft.Solutions.CosmosDB.Mongo\Microsoft.Solutions.CosmosDB.Mongo.csproj", "{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.EFCore", "libraries\Microsoft.Solutions.CosmosDB.EFCore\Microsoft.Solutions.CosmosDB.EFCore.csproj", "{3CADD477-055E-408A-8EB5-131B3F3FCEF4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{E36FC976-3345-4988-B710-C7F5DEAD2EF6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.Mongo.TODO.Service", "Sample\Microsoft.Solutions.CosmosDB.Mongo.TODO.Service\Microsoft.Solutions.CosmosDB.Mongo.TODO.Service.csproj", "{9AD83669-5DE8-44E5-9C12-BAD90FB93A23}"
@ -15,17 +11,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosD
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mongo", "Mongo", "{1FE0C1A9-B34A-4B9A-8B13-9342D28B849E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EFCore", "EFCore", "{AA2F8DEE-288D-402A-94C9-8A5BAD266FE6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.EFCore.TODO.Service", "Sample\Microsoft.Solutions.CosmosDB.EFCore.TODO.Service\Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.csproj", "{58687FB4-3218-49C2-90BF-FA214F5BE535}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.EFCore.TODO.Tests", "Sample\Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.Tests\Microsoft.Solutions.CosmosDB.EFCore.TODO.Tests.csproj", "{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.SQL", "libraries\Microsoft.Solutions.CosmosDB.SQL\Microsoft.Solutions.CosmosDB.SQL.csproj", "{A161FC5B-E3D9-4814-BFFB-90FD8AE1E158}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SDK", "SDK", "{9CF5C149-650A-42C4-A08E-0A066FE7721A}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SQL", "SQL", "{9CF5C149-650A-42C4-A08E-0A066FE7721A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.SQL.TODO.Service", "Sample\Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service\Microsoft.Solutions.CosmosDB.SQL.TODO.Service.csproj", "{79FBDE75-2C12-4684-ADCB-C8004D305373}"
EndProject
@ -33,10 +23,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosD
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB", "libraries\Microsoft.Solutions.CosmosDB\Microsoft.Solutions.CosmosDB.csproj", "{5CF6B6AA-635A-46A3-A0BC-A84294BB205E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.Test", "libraries\Microsoft.Solutions.CosmosDB.Test\Microsoft.Solutions.CosmosDB.Test.csproj", "{8786E5FD-CF17-4549-9AB3-0303A3DCC801}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.TODO.WebHost", "Sample\Microsoft.Solutions.CosmosDB.WebHost\Microsoft.Solutions.CosmosDB.TODO.WebHost.csproj", "{8926C6B9-213D-4569-A878-53204473E75E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.SQL.ChangeFeed", "Libraries\Microsoft.Solutions.CosmosDB.SQL.ChangeFeed\Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.csproj", "{45D30D7D-271F-4833-8E80-09831F79F1E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service", "Sample\Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service\Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.csproj", "{0F6953CF-37F3-4759-AF46-A62ABB49D76C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.Test", "libraries\Microsoft.Solutions.CosmosDB.Test\Microsoft.Solutions.CosmosDB.Test.csproj", "{228A0A82-EF20-459D-A9CD-564EC02A45E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Solutions.CosmosDB.Mongo", "libraries\Microsoft.Solutions.CosmosDB.Mongo\Microsoft.Solutions.CosmosDB.Mongo.csproj", "{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -44,18 +40,6 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F}.Release|Any CPU.Build.0 = Release|Any CPU
{3CADD477-055E-408A-8EB5-131B3F3FCEF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3CADD477-055E-408A-8EB5-131B3F3FCEF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3CADD477-055E-408A-8EB5-131B3F3FCEF4}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{3CADD477-055E-408A-8EB5-131B3F3FCEF4}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{3CADD477-055E-408A-8EB5-131B3F3FCEF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3CADD477-055E-408A-8EB5-131B3F3FCEF4}.Release|Any CPU.Build.0 = Release|Any CPU
{9AD83669-5DE8-44E5-9C12-BAD90FB93A23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9AD83669-5DE8-44E5-9C12-BAD90FB93A23}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9AD83669-5DE8-44E5-9C12-BAD90FB93A23}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
@ -68,18 +52,6 @@ Global
{E36ADD7C-3E12-44D5-9A56-0B5C086EF755}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{E36ADD7C-3E12-44D5-9A56-0B5C086EF755}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E36ADD7C-3E12-44D5-9A56-0B5C086EF755}.Release|Any CPU.Build.0 = Release|Any CPU
{58687FB4-3218-49C2-90BF-FA214F5BE535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58687FB4-3218-49C2-90BF-FA214F5BE535}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58687FB4-3218-49C2-90BF-FA214F5BE535}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{58687FB4-3218-49C2-90BF-FA214F5BE535}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{58687FB4-3218-49C2-90BF-FA214F5BE535}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58687FB4-3218-49C2-90BF-FA214F5BE535}.Release|Any CPU.Build.0 = Release|Any CPU
{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5}.Release|Any CPU.Build.0 = Release|Any CPU
{A161FC5B-E3D9-4814-BFFB-90FD8AE1E158}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A161FC5B-E3D9-4814-BFFB-90FD8AE1E158}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A161FC5B-E3D9-4814-BFFB-90FD8AE1E158}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
@ -104,38 +76,54 @@ Global
{5CF6B6AA-635A-46A3-A0BC-A84294BB205E}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{5CF6B6AA-635A-46A3-A0BC-A84294BB205E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CF6B6AA-635A-46A3-A0BC-A84294BB205E}.Release|Any CPU.Build.0 = Release|Any CPU
{8786E5FD-CF17-4549-9AB3-0303A3DCC801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8786E5FD-CF17-4549-9AB3-0303A3DCC801}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8786E5FD-CF17-4549-9AB3-0303A3DCC801}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{8786E5FD-CF17-4549-9AB3-0303A3DCC801}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{8786E5FD-CF17-4549-9AB3-0303A3DCC801}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8786E5FD-CF17-4549-9AB3-0303A3DCC801}.Release|Any CPU.Build.0 = Release|Any CPU
{8926C6B9-213D-4569-A878-53204473E75E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8926C6B9-213D-4569-A878-53204473E75E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8926C6B9-213D-4569-A878-53204473E75E}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{8926C6B9-213D-4569-A878-53204473E75E}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{8926C6B9-213D-4569-A878-53204473E75E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8926C6B9-213D-4569-A878-53204473E75E}.Release|Any CPU.Build.0 = Release|Any CPU
{45D30D7D-271F-4833-8E80-09831F79F1E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45D30D7D-271F-4833-8E80-09831F79F1E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45D30D7D-271F-4833-8E80-09831F79F1E5}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{45D30D7D-271F-4833-8E80-09831F79F1E5}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{45D30D7D-271F-4833-8E80-09831F79F1E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45D30D7D-271F-4833-8E80-09831F79F1E5}.Release|Any CPU.Build.0 = Release|Any CPU
{0F6953CF-37F3-4759-AF46-A62ABB49D76C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F6953CF-37F3-4759-AF46-A62ABB49D76C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F6953CF-37F3-4759-AF46-A62ABB49D76C}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{0F6953CF-37F3-4759-AF46-A62ABB49D76C}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{0F6953CF-37F3-4759-AF46-A62ABB49D76C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F6953CF-37F3-4759-AF46-A62ABB49D76C}.Release|Any CPU.Build.0 = Release|Any CPU
{228A0A82-EF20-459D-A9CD-564EC02A45E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{228A0A82-EF20-459D-A9CD-564EC02A45E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{228A0A82-EF20-459D-A9CD-564EC02A45E2}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{228A0A82-EF20-459D-A9CD-564EC02A45E2}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{228A0A82-EF20-459D-A9CD-564EC02A45E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{228A0A82-EF20-459D-A9CD-564EC02A45E2}.Release|Any CPU.Build.0 = Release|Any CPU
{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1}.DebugWithSymbol|Any CPU.ActiveCfg = Debug|Any CPU
{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1}.DebugWithSymbol|Any CPU.Build.0 = Debug|Any CPU
{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A9A678F6-7FC0-4B72-8AF1-7D4929FE212F} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
{3CADD477-055E-408A-8EB5-131B3F3FCEF4} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
{9AD83669-5DE8-44E5-9C12-BAD90FB93A23} = {1FE0C1A9-B34A-4B9A-8B13-9342D28B849E}
{E36ADD7C-3E12-44D5-9A56-0B5C086EF755} = {1FE0C1A9-B34A-4B9A-8B13-9342D28B849E}
{1FE0C1A9-B34A-4B9A-8B13-9342D28B849E} = {E36FC976-3345-4988-B710-C7F5DEAD2EF6}
{AA2F8DEE-288D-402A-94C9-8A5BAD266FE6} = {E36FC976-3345-4988-B710-C7F5DEAD2EF6}
{58687FB4-3218-49C2-90BF-FA214F5BE535} = {AA2F8DEE-288D-402A-94C9-8A5BAD266FE6}
{9CC6D04B-AD1C-4C9F-B157-3168C087DFA5} = {AA2F8DEE-288D-402A-94C9-8A5BAD266FE6}
{A161FC5B-E3D9-4814-BFFB-90FD8AE1E158} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
{9CF5C149-650A-42C4-A08E-0A066FE7721A} = {E36FC976-3345-4988-B710-C7F5DEAD2EF6}
{79FBDE75-2C12-4684-ADCB-C8004D305373} = {9CF5C149-650A-42C4-A08E-0A066FE7721A}
{7C6EAD80-D219-4792-98D7-247248918968} = {9CF5C149-650A-42C4-A08E-0A066FE7721A}
{5CF6B6AA-635A-46A3-A0BC-A84294BB205E} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
{8786E5FD-CF17-4549-9AB3-0303A3DCC801} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
{8926C6B9-213D-4569-A878-53204473E75E} = {E36FC976-3345-4988-B710-C7F5DEAD2EF6}
{45D30D7D-271F-4833-8E80-09831F79F1E5} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
{0F6953CF-37F3-4759-AF46-A62ABB49D76C} = {9CF5C149-650A-42C4-A08E-0A066FE7721A}
{228A0A82-EF20-459D-A9CD-564EC02A45E2} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
{0D8BC6A2-04D9-4A13-8C7F-96AA320BBEE1} = {F75FAB67-13B6-4A4D-8FD9-C30D4A7B648F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5A9383CD-0E2F-46A6-8783-0315851AAD4C}

Просмотреть файл

@ -1,20 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="coverlet.collector" Version="1.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB.EFCore.TODO.Service\Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,61 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;
namespace Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.Tests
{
[TestClass()]
public class TODOServiceTests
{
static TODOService todoService;
static string connString = "{put your connection string}";
static string objectId;
[TestInitialize]
public void InitTest()
{
todoService = new TODOService(connString, "COSMOSDB-EFCORE");
}
[TestMethod()]
public async Task TEST01_CreateTODOTest()
{
var result = await todoService.Create("test title", Status.New, 0, DateTime.Today, DateTime.Today.AddDays(7), "bla bla");
objectId = result.id;
}
[TestMethod()]
public async Task TEST02_UpdateTODOTest()
{
var createdTodoObj = await todoService.Find(objectId);
createdTodoObj.notes = "updated bla bla";
await todoService.Update(createdTodoObj);
}
[TestMethod()]
public async Task TEST03_SearchTODOTest()
{
var todos = await todoService.Search("updated");
foreach (var todo in todos)
{
Console.WriteLine($"{todo.id} - {todo.status} - {todo.notes}");
}
}
[TestMethod()]
public async Task TEST04_RemoveTODOTest()
{
var createdTodoObj = await todoService.Find(objectId);
Console.WriteLine($"{createdTodoObj} will be removed");
await todoService.Delete(objectId);
}
}
}

Просмотреть файл

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<OutputType>Library</OutputType>
<StartupObject></StartupObject>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\libraries\Microsoft.Solutions.CosmosDB.EFCore\Microsoft.Solutions.CosmosDB.EFCore.csproj" />
<ProjectReference Include="..\..\libraries\Microsoft.Solutions.CosmosDB\Microsoft.Solutions.CosmosDB.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,52 +0,0 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Solutions.CosmosDB.EFCore.TODO.Service
{
public class TODOService : EFCoreEntityCollectionBase<ToDo>
{
public TODOService(string DataConnectionString, string CollectionName) : base(DataConnectionString, CollectionName)
{
}
public async Task<ToDo> Create(string title, Status status, int percentComplete, DateTime startDate, DateTime endDate, string notes)
{
return await this.EntityCollection.AddAsync(
new ToDo()
{
title = title,
status = status,
percentComplete = percentComplete,
startDate = startDate,
endDate = endDate,
notes = notes
}
);
}
public async Task<ToDo> Update(ToDo todo)
{
return await this.EntityCollection.SaveAsync(todo);
}
public async Task Delete(string id)
{
await this.EntityCollection.DeleteAsync(id);
}
public async Task<ToDo> Find(string id)
{
return await this.EntityCollection.GetAsync(id);
}
public async Task<IEnumerable<ToDo>> Search(string notes)
{
return await this.EntityCollection.FindAllAsync(new GenericSpecification<ToDo>(x => x.notes.Contains(notes)));
}
}
}

Просмотреть файл

@ -5,7 +5,7 @@ using System;
namespace Microsoft.Solutions.CosmosDB.Mongo.TODO.Service.Models
{
public class ToDo : CosmosEntityBase
public class ToDo : CosmosDBEntityBase
{
public string title { get; set; }
public Status status { get; set; }

Просмотреть файл

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
@ -13,8 +13,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="1.3.0" />
</ItemGroup>

Просмотреть файл

@ -4,6 +4,7 @@
using Microsoft.Solutions.CosmosDB.Mongo.TODO.Service;
using Microsoft.Solutions.CosmosDB.Mongo.TODO.Service.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;
@ -13,7 +14,7 @@ namespace Microsoft.Solutions.CosmosDB.Mongo.TODO.Tests
public class TODOServiceTests
{
static TODOService todoService;
static string mongoConnString = "{put your connection string}";
static string mongoConnString = "{Put Your ConnectionString}";
static string objectId;
[TestInitialize]
@ -55,7 +56,7 @@ namespace Microsoft.Solutions.CosmosDB.Mongo.TODO.Tests
public async Task TEST04_RemoveTODOTest()
{
var createdTodoObj = await todoService.Find(objectId);
Console.WriteLine($"{createdTodoObj} will be removed");
Console.WriteLine($"{JsonConvert.SerializeObject(createdTodoObj)} will be removed");
await todoService.Delete(objectId);
}

Просмотреть файл

@ -0,0 +1,23 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Sample/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.csproj", "Sample/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service/"]
COPY ["libraries/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.csproj", "libraries/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed/"]
COPY ["libraries/Microsoft.Solutions.CosmosDB/Microsoft.Solutions.CosmosDB.csproj", "libraries/Microsoft.Solutions.CosmosDB/"]
COPY ["libraries/Microsoft.Solutions.CosmosDB.SQL/Microsoft.Solutions.CosmosDB.SQL.csproj", "libraries/Microsoft.Solutions.CosmosDB.SQL/"]
RUN dotnet restore "Sample/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.csproj"
COPY . .
WORKDIR "/src/Sample/Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service"
RUN dotnet build "Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Microsoft.Solutions.CosmosDB.SQL.TODO.ChangeFeed.Service.dll"]

Просмотреть файл

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<UserSecretsId>dotnet-Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service-C3808731-9407-4BE4-85FA-FA48ADFBF125</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
<AssemblyName>Microsoft.Solutions.CosmosDB.SQL.TODO.ChangeFeed.Service</AssemblyName>
<RootNamespace>Microsoft.Solutions.CosmosDB.SQL.TODO.ChangeFeed.Service</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.11.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libraries\Microsoft.Solutions.CosmosDB.SQL.ChangeFeed\Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.csproj" />
<ProjectReference Include="..\..\libraries\Microsoft.Solutions.CosmosDB.SQL\Microsoft.Solutions.CosmosDB.SQL.csproj" />
<ProjectReference Include="..\..\libraries\Microsoft.Solutions.CosmosDB\Microsoft.Solutions.CosmosDB.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -3,9 +3,9 @@
using System;
namespace Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.Models
namespace Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.Models
{
public class ToDo : CosmosEntityBase
public class ToDo : CosmosDBEntityBase
{
public string title { get; set; }
public Status status { get; set; }

Просмотреть файл

@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.Solutions.CosmosDB.SQL.TODO.ChangeFeed.Service
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"profiles": {
"Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
},
"dotnetRunMessages": "true"
},
"Docker": {
"commandName": "Docker"
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Solutions.CosmosDB.SQL.ChangeFeed;
using Microsoft.Solutions.CosmosDB.SQL.ChangeFeed.Service.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Solutions.CosmosDB.SQL.TODO.ChangeFeed.Service
{
public class Worker : Watcher<ToDo>
{
/// <summary>
/// Passing configuration by ASPnet core Dependency Injection
/// This Application sample shows how to detact changes for TODO collection by Microsoft.Solutions.CosmosDB.SQL.TODO.WebHost Demo App
/// </summary>
/// <param name="configuration">Check appsettings.json file definition</param>
public Worker(IConfiguration configuration) : base(configuration["Values:DBConnectionString"],
configuration["Values:MonitoredDatabaseName"],
configuration["Values:MonitoredContainerName"])
{
}
protected override Task OnChangedFeedDataSets(IReadOnlyCollection<ToDo> changes, CancellationToken cancellationToken)
{
//put your business logics with changes
foreach (var item in changes)
{
Console.WriteLine($"Detected operation for item with id {item.id} => {JsonConvert.SerializeObject(item)}");
}
return base.OnChangedFeedDataSets(changes, cancellationToken);
}
}
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Values": {
"DBConnectionString": "{Put Your ConnectionString}",
"MonitoredDatabaseName": "COSMOS-SQLSDK",
"MonitoredContainerName": "ToDos"
}
}

Просмотреть файл

@ -8,8 +8,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="1.3.0" />
</ItemGroup>

Просмотреть файл

@ -27,6 +27,7 @@ namespace Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service.Tests
{
var result = await todoService.Create("test title", Status.New, 0, DateTime.Today, DateTime.Today.AddDays(7), "bla bla");
objectId = result.id;
Console.WriteLine(objectId);
}
[TestMethod()]

Просмотреть файл

@ -5,7 +5,7 @@ using System;
namespace Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service.Models
{
public class ToDo : CosmosEntityBase
public class ToDo : CosmosDBEntityBase
{
public string title { get; set; }
public Status status { get; set; }

Просмотреть файл

@ -2,7 +2,7 @@
// Licensed under the MIT License.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.Models;
using Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

Просмотреть файл

@ -1,25 +1,25 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Sample/Microsoft,Solutions.CosmosDB.WebHost/Microsoft,Solutions.CosmosDB.TODO.WebHost.csproj", "Sample/Microsoft,Solutions.CosmosDB.WebHost/"]
COPY ["Sample/Microsoft.Solutions.CosmosDB.EFCore.TODO.Service/Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.csproj", "Sample/Microsoft.Solutions.CosmosDB.EFCore.TODO.Service/"]
COPY ["Sample/Microsoft.Solutions.CosmosDB.WebHost/Microsoft.Solutions.CosmosDB.TODO.WebHost.csproj", "Sample/Microsoft.Solutions.CosmosDB.WebHost/"]
COPY ["Sample/Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service/Microsoft.Solutions.CosmosDB.SQL.TODO.Service.csproj", "Sample/Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service/"]
COPY ["libraries/Microsoft.Solutions.CosmosDB/Microsoft.Solutions.CosmosDB.csproj", "libraries/Microsoft.Solutions.CosmosDB/"]
COPY ["libraries/Microsoft.Solutions.CosmosDB.EFCore/Microsoft.Solutions.CosmosDB.EFCore.csproj", "libraries/Microsoft.Solutions.CosmosDB.EFCore/"]
RUN dotnet restore "Sample/Microsoft,Solutions.CosmosDB.WebHost/Microsoft,Solutions.CosmosDB.TODO.WebHost.csproj"
COPY ["libraries/Microsoft.Solutions.CosmosDB.SQL/Microsoft.Solutions.CosmosDB.SQL.csproj", "libraries/Microsoft.Solutions.CosmosDB.SQL/"]
RUN dotnet restore "Sample/Microsoft.Solutions.CosmosDB.WebHost/Microsoft.Solutions.CosmosDB.TODO.WebHost.csproj"
COPY . .
WORKDIR "/src/Sample/Microsoft,Solutions.CosmosDB.WebHost"
RUN dotnet build "Microsoft,Solutions.CosmosDB.TODO.WebHost.csproj" -c Release -o /app/build
WORKDIR "/src/Sample/Microsoft.Solutions.CosmosDB.WebHost"
RUN dotnet build "Microsoft.Solutions.CosmosDB.TODO.WebHost.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Microsoft,Solutions.CosmosDB.TODO.WebHost.csproj" -c Release -o /app/publish
RUN dotnet publish "Microsoft.Solutions.CosmosDB.TODO.WebHost.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Microsoft,Solutions.CosmosDB.TODO.WebHost.dll"]
ENTRYPOINT ["dotnet", "Microsoft.Solutions.CosmosDB.TODO.WebHost.dll"]

Просмотреть файл

@ -1,21 +0,0 @@
FROM mcr.microsoft.com/dotnet/sdk:5.0
ARG BUILD_CONFIGURATION=Debug
ENV ASPNETCORE_ENVIRONMENT=Development
ENV ASPNETCORE_URLS=http://+:80
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
EXPOSE 80
WORKDIR /src
COPY ["libraries/Microsoft.Solutions.CosmosDB.EFCore/Microsoft.Solutions.CosmosDB.EFCore.csproj", "libraries/Microsoft.Solutions.CosmosDB.EFCore/"]
COPY ["libraries/Microsoft.Solutions.CosmosDB/Microsoft.Solutions.CosmosDB.csproj", "libraries/Microsoft.Solutions.CosmosDB/"]
COPY ["Sample/Microsoft,Solutions.CosmosDB.WebHost/Microsoft,Solutions.CosmosDB.TODO.WebHost.csproj", "Sample/Microsoft,Solutions.CosmosDB.WebHost/"]
COPY ["Sample/Microsoft.Solutions.CosmosDB.EFCore.TODO.Service/Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.csproj", "Sample/Microsoft.Solutions.CosmosDB.EFCore.TODO.Service/"]
RUN dotnet restore "Sample/Microsoft,Solutions.CosmosDB.WebHost/Microsoft,Solutions.CosmosDB.TODO.WebHost.csproj"
COPY . .
WORKDIR "/src/Sample/Microsoft,Solutions.CosmosDB.WebHost"
RUN dotnet build --no-restore "Microsoft,Solutions.CosmosDB.TODO.WebHost.csproj" -c $BUILD_CONFIGURATION
RUN echo "exec dotnet run --no-build --no-launch-profile -c $BUILD_CONFIGURATION --" > /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

Просмотреть файл

@ -9,15 +9,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.9" NoWarn="NU1605" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.0" NoWarn="NU1605" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.9" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Kubernetes.Tools.Targets" Version="1.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB.EFCore.TODO.Service\Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.csproj" />
<ProjectReference Include="..\Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service\Microsoft.Solutions.CosmosDB.SQL.TODO.Service.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -7,8 +7,8 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Microsoft.Solutions.CosmosDB.EFCore.TODO.Service;
using Microsoft.Solutions.CosmosDB.EFCore.TODO.Service.Models;
using Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service;
using Microsoft.Solutions.CosmosDB.SQL.SDK.TODO.Service.Models;
namespace Microsoft.Solutions.CosmosDB.TODO.WebHost
{