我有一个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);
}
但是我从dynamic
到IDocumentEntity
收到InvalidCastException。我假设它是因为动态对象上存在额外的属性而不是IDocumentEntity
接口上的属性?
我尝试做的是让我的文档实体保持开放状态,但是依靠一些属性来维护它们。
答案 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; }