-
Notifications
You must be signed in to change notification settings - Fork 494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SDK v3 should support interface to be passed to InsertItemAsync<T>/ReplaceItemAsync<T>/UpsertItemAsync<T> #1266
Comments
The problem is the serialization is based on the type you passed in. It's not possible to deserialize an interface. The concrete type has to be passed into the method. The reason this works in v2 is it's doing a lazy deserialization so you don't get the exception until you try to read the object which your project never does. This optimization should be done to v3, but if your really looking for performance you should use the stream APIs instead. Solutions 1:
Solution 2:
Solution 3:
|
The Solution 1 does not match my current implementation because The Solution 2 is half a solution because the project rely today on the current behavior of the SDK (Exceptions included) to ensure that the project is resilient. The Solution 3 is working thanks ! 👍 Could it be possible to have an option to avoid getting the Document back to the response ?
|
@YohanSciubukgian that's great. For solution 2 I updated it. There is a method Cosmos DB is working on supporting this option for fire and forget. It's probably a month or two away from being released. |
@j82w inserting as dynamic works. But what about querying after the document is already in the database? How can I make this work? /// <summary>
/// Queries the documents that matches the given predicate
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="predicate"></param>
/// <returns></returns>
private async Task<IQueryable<T>> QueryAsync<T>(Expression<Func<T, bool>> predicate) where T : class, IEntity
{
Container container = _context.GetContainer<T>();
QueryRequestOptions requestOptions = new()
{
MaxItemCount = -1,
MaxConcurrency = -1
};
IQueryable<T> query = container.GetItemLinqQueryable<T>(true, requestOptions: requestOptions);
if (predicate != null)
{
query = query.Where(predicate);
}
return await Task.FromResult(query);
} |
The following code should work. If it does not work please create a new issue with the exception you are seeing. private async Task<IQueryable<T>> QueryAsync<T>(Expression<Func<T, bool>> predicate) where T : class, IEntity
{
Container container = _context.GetContainer<T>();
QueryRequestOptions requestOptions = new()
{
MaxItemCount = -1,
MaxConcurrency = -1
};
// Do not use allowSynchronousQueryExecution. It does blocking calls which cause deadlock and thread starvation
IQueryable<T> query = container.GetItemLinqQueryable<T>(allowSynchronousQueryExecution: false, requestOptions: requestOptions);
if (predicate != null)
{
query = query.Where(predicate);
}
List<T> results = new List<T>();
using (FeedIterator<T> setIterator = query.ToFeedIterator<T>())
{
//Asynchronous query execution
while (setIterator.HasMoreResults)
{
var response = await setIterator.ReadNextAsync();
results.AddRange(response);
}
}
return results;
} |
Describe the bug
The scenario where the method
InsertItemAsync
/ReplaceItemAsync
/UpsertItemAsync
is called with an interface is working with the SDK v2 but not on the SDK v3.It's a blocking point to work with a schemaless database and not being able to work with interfaces to insert/replace/upsert documents.
We could have a
<T>
being aList<ICompany>
where eachICompany
has a list of common properties & each concrete has dedicated properties to the current company.This is the stacktrace I had using the SDK v3 :
To Reproduce
I created a repository with a sample usage using the SDK v2 & the SDK v3, it's available here :
https://github.com/YohanSciubukgian/CosmosDbConnector
Expected behavior
SDK v3 should support interface to be passed to generic type
<T>
while calling InsertItemAsync (like SDK v2)Actual behavior
An Exception is being raised when InsertItemAsync is being called.
Environment summary
Azure Cosmos DB emulator : v2.9.2
Microsoft.Azure.Cosmos : v3.6.0
Microsoft.Azure.DocumentDB.Core : v2.10.1
OS Version: Windows
Additional context
I have added the Type declaration
DocumentBase<T>
onCreateItemAsync
/ReplaceItemAsync
/UpsertItemAsync
method but the exception still occurs.It looks like the type is redundant :
It looks like (from the stacktrace) that the SDK v3 is trying to create an object based on the generic type for the response.
I have added a break point before the Dispose(), on the UnitTests part, in order to analyze the CosmosDB (local emulator) behavior.
It looks like the document has been created properly on CosmosDB but the response cannot be processed by the SDK v3.
The text was updated successfully, but these errors were encountered: