В этом посте рассказывается о некоторых новых функциях, добавленных в Neo4jD в последние дни.
Persist Статический типизированный объект
В предыдущем посте я объяснил, как создать Node и Relationship с помощью Neo4jD. Как вы могли заметить, свойства Node являются динамическими, например, чтобы задать FirstName, мы говорим «node.SetProperty (« FirstName »,« Sony »)». Как и я, большинству из нас не нравятся динамические свойства, поэтому мы создаем статические объекты. Этот пост посвящен тому, как сохранить статические объекты в Neo4j.
Примечание: я не против Dynamics, это просто личное предпочтение не строить вокруг Dynamics.
Давайте поговорим с некоторыми примерами.
public class Person { public Person() { this.Address = new Address(); } [EntityId] public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public Address Address { get; set; } } public class Address { [EntityId] public int AddressId { get; set; } public string Address1 { get; set; } public string City { get; set; } }
Итак, у меня есть два класса для хранения моих данных. Давайте посмотрим, как сохранить объект с помощью Neo4jD. Ядро Neo4jD основано на Node и Relationship с динамическими свойствами. Вдобавок к ядру я добавил маппер для сопоставления статических типизированных сущностей с узлами или связями. Я не собираюсь углубляться в понимание картографа, просто расскажу, например, если вам нужно больше понимания, лучше изучите Neo4jD в github .
Как сохранить объект
[TestCase] public Person SaveTest() { Person person = new Person { FirstName = "Sony", LastName= "Arouje"}; NodeMapper mapper = new NodeMapper(); person=mapper.Save<Person>(person); Console.WriteLine("Generated Id: " + person.Id.ToString()); Assert.AreNotEqual(0, person.Id); return person; }
За кулисами NodeMapper использует отражение, чтобы получить данные из объекта Person и создать объект Node. Посмотрим, как я это делаю.
public T Save<T>(T entity) where T:class { Node node = this.CreateNode<T>(entity); node.Create(); return MapperHelper.SetIdentity<T>(entity, node.Id); } private Node CreateNode<T>(T entity) where T:class { Node node = new Node(); node.AddProperty("clazz", typeof(T).ToString()); typeof(T).GetProperties().Where(pr => pr.CanRead && MapperHelper.IsAnId(pr) == false) .ToList().ForEach(property => { if(MapperHelper.IsPrimitive(property.PropertyType)) node.AddProperty(property.Name, property.GetValue(entity, null).ToString()); }); return node; }
Функция CreateNode выполняет сопоставление. Итерирует через свойство и вызывает node.AddProperty (property.Name, property.GetValue ()), это то же самое, что и node.AddProperty («FirstName», «Sony»).
Вы могли заметить, что поле Id в классе имеет атрибут EntityId. Это обязательный атрибут для получения или установки идентификатора узла в поле идентификатора объекта.
Получить экземпляр от Neo4J
[TestCase] public void GetPersonById() { NodeMapper mapper = new NodeMapper(); Person person = mapper.Get<Person>(7); Console.WriteLine("Generated Id: " + person.Id.ToString()); Assert.AreNotEqual(0, person.Id); Assert.AreEqual(“Sony”, person.FirstName); }
Чтобы получить человека, которого я назвал mapper.Get с уникальным идентификатором человека, и картограф вернет действительного человека, если он существует в БД. NodeMapper использует нижеприведенную функцию для генерации объекта.
public T Get<T>(int id) where T:class { Node node = Node.Get(id); T entity = (T)Activator.CreateInstance(typeof(T)); if (node.GetProperty("clazz")!=typeof(T).ToString()) throw new InvalidCastException(string.Format("Retrieved object with ID '{0}' is an instance of '{1}' and unable to cast it to '{2}'", id.ToString(), node.GetProperty("clazz"), typeof(T).ToString())); typeof(T).GetProperties().Where(pr => pr.CanRead && MapperHelper.IsAnId(pr) == false) .ToList().ForEach(property => { property.SetValue(entity, MapperHelper.CastPropertyValue(property, node.GetProperty(property.Name)), null); }); entity = MapperHelper.SetIdentity<T>(entity, id); return entity; }
Создать отношения
Вы можете видеть, что Person имеет экземпляр Address, в Graph Person связан с Address. Давайте посмотрим, как мы можем создать это
[TestCase] public void CanCreateRelationships() { Person person = new Person { FirsName = "Sony", LastName = "Arouje" }; person.Address.Address1 = "EcoSpace"; person.Address.City = "Bangalore"; NodeMapper mapper = new NodeMapper(); mapper.CreateRelationshipTo<Person, Address>(person,person.Address); Console.WriteLine(person.Id.ToString()); Assert.AreEqual(1, person.Id); }
Функция CreateRelationShipTo будет сохранять как Персона, так и Адрес, если она не сохранена, иначе она создаст связь. В Neo4j отношения будут персона-> адрес.
Получить человека с отношениями
[TestCase] public void CanGetRelatedNodes() { NodeMapper mapper = new NodeMapper(); Person person = mapper.Get<Person>(12); IList<Address> address = mapper.GetRelatedEntities<Person, Address>(person, typeof(Address)); Assert.AreEqual(1, address.Count); Assert.AreEqual("EcoSpace", address[0].Address1); }
Я знаю, что сохраняющиеся и извлекающие отношения немного запутаны, я буду работать над этим, чтобы сделать его более ясным и тихим.
Это все о сохранении статических объектов в Neo4j.
В следующем посте я расскажу о создании индекса, обхода с использованием Germlin и REST.