2017-04-15 61 views
0

我有一个DocumentDb数据库的存储库。我的文档都有一组共同属性,所以所有文档都实现了IDocumentEntity接口。是否有可能在C#中有额外的(忽略)属性?

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我知道所有的属性。但是,当然,对于一个Document Db来说最棒的是我不需要知道所有的属性(并且在很多情况下我不会)。

所以我的客户端提交有点像这个 -

{unknownProperty1: 1, unknownProperty2: 2}

而且我想这UPSERT使用我的文档库。

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

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

    _otherDocumentRepository.Set(entity); 
} 

,但我得到一个InvalidCastException从dynamicIDocumentEntity。我认为这是因为动态对象上存在的额外属性,但不在IDocumentEntity接口上?

我想要做的事情是让我的文档实体处于动态状态,但依靠一些属性来维护它们。

回答

0

传递给UpsertDocument的实体参数应该明确地实现IDocumentEntity,以使代码有效,仅仅具有Id属性是不够的。

一些选项:

1)代理可以应用于:

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; } 
     } 
} 

...用

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

所存储的文件将具有嵌套的对象属性,这可能是不能接受的

2)有一个lib https://github.com/ekonbenefits/impromptu-interface它创建代理dynamica lly 并且不会像上面的解决方案那样产生额外的属性。 缺点是性能不佳。

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

public void UpsertDocument(IDocumentEntity entity){...} 
public void UpsertDocument(dynamic entity){...} 

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

+0

这是不幸的,但似乎是它必须要走的路 –

0

如果你有一定的灵活性,以如何命名的动态属性,你可以把它们塞进你的对象上的字典属性:

public Dictionary<string, dynamic> extra { get; set; } 
相关问题