Skip to content
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

Cosmos DB: Is there ANY way to currently support IDictionary<string, object> #21265

Closed
DaleyKD opened this issue Jun 15, 2020 · 11 comments
Closed

Comments

@DaleyKD
Copy link

DaleyKD commented Jun 15, 2020

I've been working all week trying to get EF Core 3.1 Cosmos DB provider to even somewhat work with an IDictionary<string, object>. So far, nothing is working ideally.

Is there a way to use a Value Converter? A Backing Field? Anything like that?

This limitation is making it so that I can't use EF Core for my Cosmos project.

@ajcvickers
Copy link
Member

@DaleyKD Can you provide more details on where the dictionary appears in the C# model and what the expected mapping to JSON would be?

@DaleyKD
Copy link
Author

DaleyKD commented Jun 15, 2020

Ideally:

public class Foo
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [JsonProperty("id")]
    public Guid ID { get; set; }

    [Required]
    [JsonProperty("partKey")]
    public string PartitionKey { get; set; } = string.Empty;

    [JsonProperty("metaDict")]
    public IDictionary<string, object> MetadataDictionary { get; set; } = new Dictionary<string, object>();

    [JsonProperty("url")]
    public string Url { get; set; }
}

And the results would look like what CosmosClient writes:

{
    "metaDict": {
        "@odata.etag": "\"982b588c-a06b-4f2e-b6dd-9732bdbbf143,20\"",
        "Title": "A Compliance Title",
        "GovernmentIDNumber": "8807",
        "Salary": 123456.78,
        "Location": "1600 Pennsylvania Ave NW\r\nWashington, DC 20500",
        "ContentType": "Document",
        "Created": "2020-05-28T17:03:48Z",
        "AuthorLookupId": "1073741822",
        "Modified": "2020-06-15T19:30:57Z",
        "EditorLookupId": "1073741822",
        "DocIcon": "png",
        "FileSizeDisplay": "14622",
        "ItemChildCount": "0",
        "FolderChildCount": "0",
        "_ComplianceFlags": "",
        "_ComplianceTag": "",
        "_ComplianceTagWrittenTime": "",
        "_ComplianceTagUserId": "",
        "_CommentCount": "",
        "_LikeCount": "",
        "_DisplayName": "",
        "AppAuthorLookupId": "7",
        "AppEditorLookupId": "7",
        "Edit": "0",
        "_UIVersionString": "19.0",
        "ParentVersionStringLookupId": "6",
        "ParentLeafNameLookupId": "6"
    },
    "url": "https://google.com/test.png",
    "id": "dac9bcfa-1c68-498f-95bd-4f7443752a05",
    "partKey": "202006",
    "Discriminator": "Foo",
    "_rid": "hwE9AKmqH1oBAAAAAAAAAA==",
    "_self": "dbs/hwE9AA==/colls/hwE9AKmqH1o=/docs/hwE9AKmqH1oBAAAAAAAAAA==/",
    "_etag": "\"00000000-0000-0000-434b-7f41007b01d6\"",
    "_attachments": "attachments/",
    "_ts": 1592249459
}

@AndriySvyryd
Copy link
Member

Duplicate of #9914

@DaleyKD
Copy link
Author

DaleyKD commented Jun 16, 2020

Maybe I'm dense, but closing this out doesn't answer my question. Is it even possible to do this in EF Core 3.1 at all?

@AndriySvyryd
Copy link
Member

@DaleyKD No, there's no way of doing this in 3.1. You can try accessing the JSON directly as a workaround https://docs.microsoft.com/en-us/ef/core/providers/cosmos/unstructured-data

@DaleyKD
Copy link
Author

DaleyKD commented Jun 16, 2020

@AndriySvyryd : Thank you! That's all I needed so I didn't go insane. :)

@DaleyKD
Copy link
Author

DaleyKD commented Jun 16, 2021

@AndriySvyryd - With EF Core 5.0 (or maybe even upcoming 6), is this possible yet?

Currently, I can't use EF Core with Cosmos because of this limitation. I still have to use the CosmosClient. ValueConverters? Anything?

(I'm a little embarrassed by what I currently have as my CosmosDbService because it's a nasty mix of EF Core and CosmosClient while I want to convert to full EF Core.)

@AndriySvyryd
Copy link
Member

In EF Core 5 you can map them as owned shared type entity types:

modelBuilder.Entity<Foo>().OwnsOne(
    "FooMetadata",
    o => o.MetadataDictionary,
    d =>
    {
        d.Property<string>("Title");
        d.Property<string>("GovernmentIDNumber");
        ...
    });

@DaleyKD
Copy link
Author

DaleyKD commented Jun 17, 2021

If my MetadataDictionary is always dynamic, and I'm never fully sure what's in it, how can I possibly do this? It's a property bag of Metadata. It may or may not have a Title, it may or may not have "Grandma's Favorite Casserole."

@AndriySvyryd
Copy link
Member

@DaleyKD That's tracked by #2282 and specifically for Cosmos by #14762 and possibly #20584

@DaleyKD
Copy link
Author

DaleyKD commented Jun 17, 2021

Perfect. Thank you!

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants