是否可以在C#中使用额外(忽略)属性?

时间:2017-04-15 13:16:34

标签: c# azure-cosmosdb nosql

我有一个DocumentDb数据库的存储库。我的文档都有一组公共属性,因此所有文档都实现了IDocumentEntity接口。

public interface IDocumentEntity {
    [JsonProperty("id")]
    Guid Id { get; set; }

    [JsonProperty("documentClassification")]
    DocumentClassification DocumentClassification { get; set; }
}

public class KnownDocument : IDocumentEntity {
    [JsonProperty("id")]
    Guid Id { get; set; }

    [JsonProperty("documentClassification")]
    DocumentClassification DocumentClassification { get; set; }

    [JsonProperty("knownProperty")]
    string KnownProperty { get; set; }
}

public class BaseDocumentRepository<T> where T : IDocumentEntity {
    public Set(T entity) {
        // ... stuff
    }
}

这适用于KnownDocument,我知道所有属性。但是,当然,文档Db的优点在于我不需要知道所有属性(在很多情况下我都不知道)。

所以我的客户提交了类似的内容 -

{unknownProperty1: 1, unknownProperty2: 2}

我想使用我的文档存储库来支持它。

public OtherDocumentService() {
_otherDocumentService = new OtherDocumentRepository();
}

public UpsertDocument(dynamic entity) {
    entity.id = new Guid();
    entity.documentClassification = DocumentClassification.Other;

    _otherDocumentRepository.Set(entity);
}

但是我从dynamicIDocumentEntity收到InvalidCastException。我假设它是因为动态对象上存在额外的属性而不是IDocumentEntity接口上的属性?

我尝试做的是让我的文档实体保持开放状态,但是依靠一些属性来维护它们。

2 个答案:

答案 0 :(得分:0)

传递给UpsertDocument的实体参数应该显式实现IDocumentEntity以使代码正常工作,仅仅具有Id属性是不够的。

一些选项:

1)可以申请代理:

npm run build

...使用

public class ProxyDocumentEntity : IDocumentEntity
{
        public dynamic Content { get; private set; }

        public ProxyDocumentEntity(dynamic @content)
        {
            Content = @content;
        }

        public Guid Id
        {
            get { return Content.Id; }
            set { Content.Id = value; }
        }
}

存储的文档将具有嵌套的Object属性,这可能是不可接受的

2)有一个lib https://github.com/ekonbenefits/impromptu-interface可以动态创建代理 并没有像上面的解决方案那样制造额外的财产 缺点将在于表现。

从技术上讲,它可能是两种方法:

public void UpsertDocument(dynamic entity)
{
            entity.Id = new Guid();         
            repo.Set(new ProxyDocumentEntity(entity));
}

所以第一个(快速)将对实现IDocumentEntity的对象起作用,对其余对象起第二个(慢)。 但这是一个猜测,因为我不知道你所拥有的项目的整个代码库的细节。

答案 1 :(得分:0)

如果您对如何命名这些动态属性有一定的灵活性,可以将它们填充到对象的Dictionary属性中:

 public Dictionary<string, dynamic> extra { get; set; }