How to get all items of container in cosmos db with dotnet core - linq

Hi I would like to get all items of a container in a database in cosmos DB. I can see that there are already a lot of methods available but I don't see any getAllItems or a lookalike.
Is there an easy way to do it like using LINQ or something?
Thanks

If you want to do this using Linq, you can do the following (As suggested in this answer here: How can I use LINQ in CosmosDB SDK v3.0 async query?):
var db = Client.GetDatabase(databaseId);
var container = db.GetContainer(containerId);
var q = container.GetItemLinqQueryable<Person>();
var iterator = q.ToFeedIterator();
var results = await iterator.ReadNextAsync();
If you want a non-Linq solution, use this (taken from the v3 SDK samples: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/ItemManagement/Program.cs#L259:
QueryDefinition query = new QueryDefinition(
"select * from sales s where s.AccountNumber = #AccountInput ")
.WithParameter("#AccountInput", "Account1");
FeedIterator<SalesOrder> resultSet = container.GetItemQueryIterator<SalesOrder>(
query,
requestOptions: new QueryRequestOptions()
{
PartitionKey = new PartitionKey("Account1"),
MaxItemCount = 1
});
while (resultSet.HasMoreResults)
{
FeedResponse<SalesOrder> response = await resultSet.ReadNextAsync();
// Work through iterator list here
}
Hope this helps!

You can use LINQ like described in Microsoft Azures documentation.
Something like this should be the solution of your problem:
var db = Client.GetDatabase(databaseId);
var container = db.GetContainer(containerId);
//Get iterator or use some LINQ queries here
var iterator = container.GetItemLinqQueryable<YourType>().GetEnumerator();

Related

Get to underlying SQL for Cosmos DB Query generated via LINQ

I am creating a query to cosmos using Linq
This is converted into SQL which is then run to do the search
var modelName = "Mondeo";
var baseQuery = client.CreateDocumentQuery<Car>(StaticSettings.ProjectionsCollectionUri,
new FeedOptions { MaxItemCount = maxItemCount, PartitionKey = new PartitionKey(partitionKey) })
.Where(order => car.ModelName == modelName);
If I run this code and put a breakpoint after this statement, I can see the raw SQL query generated
This is shown in the first line of the inspector
{{"query":"SQL HERE"}}
How can I get to this via code?
I am looking to get to this SQL to ensure that it is what I want it to be and I can use it in my tests
Paul
Assuming you're using Visual Studio, the debugger by default would be showing you the output of ToString() in the inspector for any given object.
With that knowledge, you could retrieve that same query string object with the following code.
var serializedQuery = baseQuery.ToString(); // "{{\"query\":\"SQL HERE\"}}"
The result appears to be a serialized JSON object that wraps the actual SQL query. You can easily extract the SQL with Newtonsoft.Json using the following code.
var sql = JObject.Parse(serializedQuery)["query"].Value<string>(); \\ "SQL HERE"
EDIT: In current versions of the SDK, the solution would look like the following instead.
var baseQuery = container
.GetItemLinqQueryable<Car>(
requestOptions: new QueryRequestOptions
{
MaxItemCount = maxItemCount,
PartitionKey = new PartitionKey(partitionKey)
}
)
.Where(order => car.ModelName == modelName);
var sql = baseQuery.ToQueryDefinition().QueryText; // "SQL HERE"

Create publisher dynamically with conditions

I'm just looking for an idea for converting this pseudo code into a reactive style.
var records = new ArrayList<>();
var query = new Query();
var results = query.executeQuery();
records.addAll(results.getRecords());
while (results.hasMore()) {
query = new Query(results.offset())
deals = hubspotQuery.executeQuery(Deals.class);
records.addAll(results.getRecords());
}
The idea is to collect all records into a Flux
Here is one possible solution. Maybe there is others, but this one is simple.
This is not real code, but it describe the logic.
Flux<Records> query = createFluxQuery();
query.expand(record -> (record.hasMore()) ? createFluxQuery(record.offset) : Flux.empty());

How to execute Linq queries in Serenity

I have created an application using Serenity framework. I have completed basic functionality for CRUD using serenity. Based on my tables I need to have graphical representations, any charts like high charts, D3 charts or any .
1. How can I get data from the tables using Linq in serenity
Finally I have found the answer for this. We can use sql queries as well as stored procedure to fetch data from DB. I have used stored procedure and linq to get the data from db.
In repository page you can add Linq,
public ListResponse<MyRow> GetUsers(IDbConnection connection)
{
// This must be te Repository
var myRepos = new UserRepository();
// This must be a type of Request (in this case ListRequest)
var request = new ListRequest();
request.Take = 100;
// This must be a type of Response (in this case ListResponse)
var response = new ListResponse<MyRow>();
// This must be called on Repository
var result = myRepos.List(connection, request);
// Data
var data = result.Entities.Where(r => r.Name != "").ToList();
response.Entities = data;
return response;
}
I have already defined MyRow as UserRow like this using MyRow = Entities.UserRow;.
Hope this will help you.

CRM Linq find all parents that have 0 children

How can I find (preferably using CRM Linq) parent entities that have 0 children. For example how can I find all accounts that have 0 contacts.
If you are going to use the query expression route, which I would recommend then the following code will be useful
var entityAlias = "con";
var query = new QueryExpression
{
EntityName = "account",
ColumnSet = new ColumnSet(true),
Criteria =
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression(entityAlias, "contactid",ConditionOperator.Null)
}
}
LinkEntities =
{
new LinkEntity
{
EntityAlias = entityAlias,
LinkFromEntityName = "account",
LinkFromAttributeName = "accountid",
LinkToEntityName = "contact",
LinkToAttributeName = "parentcustomerid",
Columns = new ColumnSet("parentcustomerid", "contactid"),
JoinOperator = JoinOperator.LeftOuter,
}
},
};
var response = service.RetrieveMultiple(query);
var accounts = response.Entities;
In this code I have not limited the columns, this will reduce performance and you should only return the columns needed.
If there is the case for more than 5000 records are going to be returned then you will need to use paging and loop the query to find all the entities,
This can be found here:
https://msdn.microsoft.com/en-us/library/gg327917.aspx
However if you are certain you want to use LINQ then you can use the following code:
public static IEnumerable<Account> FindAccountsWithNoContacts()
{
var contactRelationship = new Relationship("contact_customer_accounts");
foreach(var account in XrmContext.AccountSet)
{
XrmContext.LoadProperty(contactRelationship);
if(!account.RelatedEntities.ContainsKey(contactRelationship)
yield return account;
}
}
My problem with the LINQ code is that all the enities, both the account and contact entities, will be loaded into memory. With large entity sets this can cause OutOfMemoryException, whereas the query expression route will pass the query to the Dynamics server to execute; which should make the execution of the code faster.
The thing you are looking for is left outer join. Which is unfortunately not possible in CRM using LINQ. However you can do it using query expression or FetchXML.
Here is a link that can help you:
https://community.dynamics.com/crm/b/gonzaloruiz/archive/2014/02/23/all-about-outer-join-queries-in-crm-2011-and-crm-2013

Insert data to ElasticSearch using NEST API

I am trying to insert\bulk insert data to Elastic using NEST API.
Can someone provide me the example using NEST?
Thanks,
Sameer
NEST documantation contains examples how to do this e.g.:
var descriptor = new BulkDescriptor();
foreach (var i in Enumerable.Range(0, 1000))
{
descriptor.Index<ElasticSearchProject>(op => op
.Document(new ElasticSearchProject {Id = i})
);
}
var result = client.Bulk(descriptor);
Also you can use IndexMany which is quite useful
var documents= new List<ElasticSearchProject> {...};
client.IndexMany(documents);
Good luck.

Resources