将派生接口 类 与 NEST 和 ElasticSearch 结合使用
Using Interface Derived Classes with NEST and ElasticSearch
我正在尝试使用 NEST 2.X 和 Elastic Search 来持久存储用户。每个用户都包含一个角色列表,这些角色定义了他们在我们平台内的权限。
有几种不同类型的角色,每一种都派生自 IMediaDetectionRole 接口:
public class MediaDetectionUser
{
public string Username { get; set; }
public ICollection<IMediaDetectionRole> Roles { get; set; }
public MediaDetectionUser()
{
Roles = new List<IMediaDetectionRole>();
}
}
public interface IMediaDetectionRole
{
string Name { get; }
string GetDescription();
string GetRoleType {get;}
}
[ElasticsearchType(Name="MediaDetectionAdminRole")]
public class MediaDetectionAdminRole : IMediaDetectionRole
{
public string Name { get { return "Admin"; } }
public string GetDescription() { return "Admin users can create other users within the account"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
[ElasticsearchType(Name = "MediaDetectionManagerRole")]
public class MediaDetectionManagerRole : IMediaDetectionRole
{
public string Name { get { return "Manager"; } }
public string GetDescription() { return "Managers can modify account-level properties"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
[ElasticsearchType(Name = "MediaDetectionCreatorRole")]
public class MediaDetectionCreatorRole : IMediaDetectionRole
{
public string Name { get { return "Creator"; } }
public string GetDescription() { return "Creators can create new Media Detection Profiles"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
我在ElasticSearch 中存储数据没有任何问题,但是当我去查询数据时,数据NEST 无法确定这些角色的类型。我得到:
Could not create an instance of type IMediaDetectionRole.
Type is an interface or abstract class and cannot be instantiated.
Path 'hits.hits[0]._source.roles[0].name', line 1, position 343.
将嵌套对象数据映射回正确的 class 类型的正确方法是什么?
非常感谢!
-Z
好吧,所以我想这不是一个 NEST/ES 问题,而是一个 JSON.NET 问题。显然,这个问题的解决方案涉及告诉 JSON.NET 为列表的每个成员提供类型提示。
根据@MartijnLaarman 的建议,我向角色 属性 添加了一个 [JsonProperty] 属性。见下文:
public class MediaDetectionUser
{
public string Username { get; set; }
//This JsonProperty helps reference the types during deserialization
[JsonProperty("Roles", ItemTypeNameHandling = TypeNameHandling.All)]
public ICollection<IMediaDetectionRole> Roles { get; set; }
public MediaDetectionUser()
{
Roles = new List<IMediaDetectionRole>();
}
}
这里有一个 JSON 的例子,它出现在 ElasticSearch 的 _source 中:
Roles: [
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionAdminRole, MediaDetectionFrontend.ServiceModel",
name: "Admin",
getRoleType: "MediaDetectionAdminRole"
},
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionCreatorRole, MediaDetectionFrontend.ServiceModel",
name: "Creator",
getRoleType: "MediaDetectionCreatorRole"
},
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionEditorRole, MediaDetectionFrontend.ServiceModel",
name: "Editor",
getRoleType: "MediaDetectionEditorRole"
}
]
您可以看到 $type 属性现在提供了列表中每个元素的完整类型描述符。
非常感谢@MartijnLaarman 帮助我解决了这个问题,尽管它确实与 ElasticSearch 和 NEST 无关。
我正在尝试使用 NEST 2.X 和 Elastic Search 来持久存储用户。每个用户都包含一个角色列表,这些角色定义了他们在我们平台内的权限。
有几种不同类型的角色,每一种都派生自 IMediaDetectionRole 接口:
public class MediaDetectionUser
{
public string Username { get; set; }
public ICollection<IMediaDetectionRole> Roles { get; set; }
public MediaDetectionUser()
{
Roles = new List<IMediaDetectionRole>();
}
}
public interface IMediaDetectionRole
{
string Name { get; }
string GetDescription();
string GetRoleType {get;}
}
[ElasticsearchType(Name="MediaDetectionAdminRole")]
public class MediaDetectionAdminRole : IMediaDetectionRole
{
public string Name { get { return "Admin"; } }
public string GetDescription() { return "Admin users can create other users within the account"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
[ElasticsearchType(Name = "MediaDetectionManagerRole")]
public class MediaDetectionManagerRole : IMediaDetectionRole
{
public string Name { get { return "Manager"; } }
public string GetDescription() { return "Managers can modify account-level properties"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
[ElasticsearchType(Name = "MediaDetectionCreatorRole")]
public class MediaDetectionCreatorRole : IMediaDetectionRole
{
public string Name { get { return "Creator"; } }
public string GetDescription() { return "Creators can create new Media Detection Profiles"; }
public string GetRoleType { get { return this.GetType().Name; } }
}
我在ElasticSearch 中存储数据没有任何问题,但是当我去查询数据时,数据NEST 无法确定这些角色的类型。我得到:
Could not create an instance of type IMediaDetectionRole.
Type is an interface or abstract class and cannot be instantiated.
Path 'hits.hits[0]._source.roles[0].name', line 1, position 343.
将嵌套对象数据映射回正确的 class 类型的正确方法是什么?
非常感谢!
-Z
好吧,所以我想这不是一个 NEST/ES 问题,而是一个 JSON.NET 问题。显然,这个问题的解决方案涉及告诉 JSON.NET 为列表的每个成员提供类型提示。
根据@MartijnLaarman 的建议,我向角色 属性 添加了一个 [JsonProperty] 属性。见下文:
public class MediaDetectionUser
{
public string Username { get; set; }
//This JsonProperty helps reference the types during deserialization
[JsonProperty("Roles", ItemTypeNameHandling = TypeNameHandling.All)]
public ICollection<IMediaDetectionRole> Roles { get; set; }
public MediaDetectionUser()
{
Roles = new List<IMediaDetectionRole>();
}
}
这里有一个 JSON 的例子,它出现在 ElasticSearch 的 _source 中:
Roles: [
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionAdminRole, MediaDetectionFrontend.ServiceModel",
name: "Admin",
getRoleType: "MediaDetectionAdminRole"
},
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionCreatorRole, MediaDetectionFrontend.ServiceModel",
name: "Creator",
getRoleType: "MediaDetectionCreatorRole"
},
{
$type: "MediaDetectionFrontend.ServiceModel.Types.MediaDetectionEditorRole, MediaDetectionFrontend.ServiceModel",
name: "Editor",
getRoleType: "MediaDetectionEditorRole"
}
]
您可以看到 $type 属性现在提供了列表中每个元素的完整类型描述符。
非常感谢@MartijnLaarman 帮助我解决了这个问题,尽管它确实与 ElasticSearch 和 NEST 无关。