解析 Gremlin.Net 响应的最佳方法?

问题描述 投票:0回答:4

Gremlin.Net 回复中获取 POCO 的最佳方式是什么?

现在我手动转换到字典:

var results = await gremlinClient.SubmitAsync<Dictionary<string, object>>("g.V()");
var result = results[0];
var properties = (Dictionary<string, object>)result["properties"];
var value = ((Dictionary<string, object>)properties["myValue"].Single())["value"];
azure-cosmosdb gremlin
4个回答
7
投票

我发现

GremlinClient
只能返回动态对象,如果你将其他任何东西作为类型,它就会失败(除非我只是做错了什么)。

我最终所做的是将动态对象序列化为 JSON,然后将其反序列化回我想要的对象类型:

var results = await gremlinClient.SubmitAsync<dynamic>("g.V()");
JsonConvert.DeserializeObject<MyResult>(JsonConvert.SerializeObject(results));

动态对象只是一个字典,但如果您首先序列化它,它就会具有适当的字段/属性层次结构,然后可以将其反序列化为您实际期望的内容。

必须进行额外的转换似乎有点痛苦,但这是我让它发挥作用的唯一方法。


2
投票

您可以使用类似于

的MyClass来获取您的属性
    class ProviderProperties {
        public object Name { get; set; }
        public object contact { get; set; }
        public object requesttype { get; set; }
        public object address { get; set; }
        public object phone { get; set; }
        public object description { get; set; }
        public object otherState { get; set; }
        public object otherCity { get; set; }
        public object addressStreet { get; set; }
    }

    class MyClass {
        public string id { get; set; }
        public string label { get; set; }
        public string type { get; set; }
        public ProviderProperties properties { get; set; }
    }

并将其用于

JsonConvert.DeserializeObject<MyClass>(JsonConvert.SerializeObject(results));

0
投票

尝试这个方法

IGremlinClient janusClient = JanusGraphClientBuilder.BuildClientForServer(new  GremlinServer("localhost", 8182)).Create();
GraphTraversalSource g = Traversal().WithRemote(new DriverRemoteConnection(janusClient));

IList<Vertex> x =  g.V().HasLabel("YourLabel").Has("YourpPopertyName", "some value").ToList();

0
投票

由于 Gremlin.NET 的响应是 JSON,如嵌套的 Dictionary 或 Dictionary 和 List,因此逻辑上是与动态事物搭配。如果你认为 Expando 是通用的动态 POCO,你可以创建 converter(需要是递归转换器)并使用动态魔法。如果您想编写 POCO 结构/类的卡通,另一种方法是更好地编写来自 Castle Core 的接口和 DictionaryAdapter 来适应您对接口的响应:

     ICharacter character=new DictionaryAdapterFactory().GetAdapter<ICharacter>(response)
    
    //use as
    //character.goals[0].description
    
      public interface ICharacter:IElement
        {
            
    
            [DictionaryAdapter(typeof(ICharacterProperties))]
            ICharacterProperties properties { get; set; }
       
    
          [ListOfDictionariesAdapter(typeof(List<IGoal>))]
            List<IGoal> goals { get; set; }
        }
    
    
    
        public interface IElement
        {
            string label { get; set; }
            long id { get; set; }
        }
    
        public interface IGoal
        {
            string description { get; set; }
           
        }


...other interfaces

您需要编写 2 个属性来处理嵌套字典和字典列表。

using System;
    using System.Collections;
    using Castle.Components.DictionaryAdapter;
    
    namespace x
    {
        public class DictionaryAdapterAttribute : DictionaryBehaviorAttribute,
            IPropertyDescriptorInitializer, IDictionaryPropertyGetter
        {
            private Type __type;
    
          
            public DictionaryAdapterAttribute(Type type)
            {
                __type = type;
            }
    
    
            public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, object storedValue,
                PropertyDescriptor property, bool ifExists)
            {
                if (storedValue != null && storedValue.GetType().IsGenericType &&
                    storedValue is IDictionary dictionary)
                {
                    var adapter = dictionaryAdapter.Meta.Factory.GetAdapter(__type,
                        dictionary);
    
                    dictionaryAdapter.SetProperty(key, ref adapter);
                   
                }
    
                return storedValue;
            }
    
            public void Initialize(PropertyDescriptor propertyDescriptor, object[] behaviors)
            {
                propertyDescriptor.Fetch = true;
            }
        }
    }
    
        
        
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using Castle.Components.DictionaryAdapter;
        
        namespace X
        {
             /// <summary>
                ///  will convert List<Dictionaries> to List<of addapters of Dictionaries>(default) or some other Collection Class
                ///  which should have constructor accepting IEnumerable
                /// </summary>
                public class ListOfDictionariesAdapterAttribute : DictionaryBehaviorAttribute,
                    IPropertyDescriptorInitializer, IDictionaryPropertyGetter
                {
                    private Type __type;
                    private bool __adapted;
        
                    public ListOfDictionariesAdapterAttribute(Type type)
                    {
                        __type = type;
                    }
        
        
                   
        
                    public object GetPropertyValue(IDictionaryAdapter dictionaryAdapter, string key, object storedValue,
                        PropertyDescriptor property, bool ifExists)
                    {
                        // var o = dictionaryAdapter.GetProperty(key, ifExists);
        
                        if (!__adapted && storedValue != null && storedValue.GetType().IsGenericType &&
                            storedValue is IEnumerable enumerable)
                        {
                            
                            if (enumerable.GetType().GetGenericArguments()[0] != __type)
                            {
                                var enumerator = enumerable.GetEnumerator();
                                var genericArgument = __type.GetGenericArguments()[0];
                                IList ilistWrapper =
                                    Activator.CreateInstance(typeof(List<>).MakeGenericType(genericArgument)) as IList;
                               
                                while (enumerator.MoveNext())
                                {
                                    if (enumerator.Current is IDictionary current)
                                        ilistWrapper?.Add(dictionaryAdapter.Meta.Factory.GetAdapter(genericArgument,
                                            current));
                                }
        
                                object list;
                                
                                if (__type.GetGenericTypeDefinition()==typeof(List<>))
                                {
                                    //instead of List<Dictionaries> swap with List<adapters of Dictionaries>
                                    list = ilistWrapper;
                                }
                                else
                                {
                                    //!! Note maybe use https://github.com/GriffinPlus/dotnet-libs-fastactivator instead of 
                                    //collection must have constructor that accept enumerable as params
                                    list = Activator.CreateInstance(__type, ilistWrapper);
        
                                    //v2 only for ObservableLinkedList,List
                                    // var methodInfo = list.GetType().GetMethod("AddLast",new Type[]{genericArgument});
                                    //
                                    // enumerator.Reset();
                                    //
                                    // while (enumerator.MoveNext())
                                    // {
                                    //     var adapter = dictionaryAdapter.Meta.Factory.GetAdapter(genericArgument,
                                    //         (IDictionary) enumerator.Current);
                                    //     methodInfo?.Invoke(list,new object[]{adapter});
                                    // }
                            }
    
                            dictionaryAdapter.SetProperty(key, ref list);
    
                            __adapted = true;
                        }
                    }
    
    
                    return storedValue;
                }
    
                public void Initialize(PropertyDescriptor propertyDescriptor, object[] behaviors)
                {
                    propertyDescriptor.Fetch = true;
                }
            }
    }
© www.soinside.com 2019 - 2024. All rights reserved.