Store Array of Strings with EF Core & CosmosDB

Shahab Ganji
2 min readMar 13, 2022

--

Once in our company, there was the need to store an string[] in a document in the CosmosDB, however as you might know it is not supported to have IReadOnlyCollection being stored to the database, there are questions in Stack Overflow regarding this topic with different implementations and suggestions. One of the common answers is to serialize the values as a string and store it in a string property on CosmosDB, and then deserialize it to an string[] or types of the same type. One of the things I don’t like in this approach is that the stored value on the database is not really well formatted and not like the underlying data structure.

Let’s see the problem in action, consider there is a Book class with a property of Tags as an array of strings, or types of similar representation.

When you want to add a new instance of the Book class to a DbSet<Book> and save the changes, an error will be thrown:

To address this issue, different approaches has been developed, almost all of them suggesting using a JSON serializer to achieve the goal, check this thread.

However, I used a conversion between IReadOnlyCollection<string>, and string[], the former as the type on my model, and the latter as the target type to be stored on the CosmosDB by EF Core.

As simple as that, then in the configuration file for the entity, you need to specify that

The final document stored on the database will look something similar to this:

Conclusion

There are always advantages and disadvantages to any approach, one of the downfalls of this approach is that if you want to use an In-Memory implementation of the EF Core, for the sake of some test scenarios, you will still have an issue and this will not work well there. However, I’d rather to have my model and the database clean, and write some e2e tests without replacing the actual dialect of the EF Core; for integration tests I could still use patterns like Repository and Unit Of Work and mock their behavior.

I hope you find this article helpful, you could check out the source code for this on GitHub. To run the application, you need a CosmosDB account and put the required values for connecting to it in the appsettings.json. Have a nice day and enjoy coding 😊

PS: In Entity Framework Core 6.0, you could IList<string> and IDictionary and they support storing array of primitive types; check this answer on GitHub.

--

--