{"id":22336506,"url":"https://github.com/mdfrenchman/schematica-dotnet-neo4j","last_synced_at":"2025-07-29T22:32:16.526Z","repository":{"id":143391587,"uuid":"187529715","full_name":"mdfrenchman/schematica-dotnet-neo4j","owner":"mdfrenchman","description":"Neo4j.Schema: Tools to manage Neo4j Schema for a Domain Layer in .NET","archived":false,"fork":false,"pushed_at":"2024-04-25T19:56:33.000Z","size":132,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-29T00:23:25.667Z","etag":null,"topics":["csharp","neo4j","nuget-package","schema"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mdfrenchman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-05-19T21:25:41.000Z","updated_at":"2024-04-27T14:24:56.000Z","dependencies_parsed_at":"2024-01-23T21:46:07.349Z","dependency_job_id":"dafbffe3-a9d1-4be3-a94f-b68e49e26f21","html_url":"https://github.com/mdfrenchman/schematica-dotnet-neo4j","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdfrenchman%2Fschematica-dotnet-neo4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdfrenchman%2Fschematica-dotnet-neo4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdfrenchman%2Fschematica-dotnet-neo4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mdfrenchman%2Fschematica-dotnet-neo4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mdfrenchman","download_url":"https://codeload.github.com/mdfrenchman/schematica-dotnet-neo4j/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227914149,"owners_count":17839212,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","neo4j","nuget-package","schema"],"created_at":"2024-12-04T06:06:57.373Z","updated_at":"2024-12-04T06:06:58.025Z","avatar_url":"https://github.com/mdfrenchman.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SchematicNeo4j\nA code-first approach to manage a consistent Neo4j graph schema for a domain layer that is defined in a .NET library.\n\n## For Developers\n\n## New in version 5.0.0\n- Relationship Attributes and Relationship Range Index.\n- Added default and user specified names for indexes and constraints.\n- Added NodeKeyName to the NodeAttribute, allowing for override of the default **nk{firstLabel}**.\n- Keeps consistency check by entityName and properties. Covers cases where existing constraints or indexes may already have a generic name from being defined in v3.\n\n#### Upcoming in the next minor release\n- Index types other than Range Indexes.\n#### Future change\n- **potentially breaking change** Changing Extension and CRUD methods to a Fluent pattern to make method discovery and use easier.  \n\t- `typeof(Class1).Label()` makes autocomplete method discovery difficult. I'd like to simplify that.\n- methods to list schema for export and comparison.\n\n### Using Range Index\nRelationship Range Index was added in v5.0.0 and works the same as Indexes on Nodes, except that it ignores the Label and IsAbstract properties.\nThe `Indexes.Create()` logic uses the class level attribute to differentiate between Relationship | Node.\n\n```csharp\n[Relationship]\npublic class PlaysFor {\n\n\t[Index()]\n\t[Index(Name=\"PlaysFor_YearPosition\")]\n\tpublic int Year { get; set; }\n\t\n\t[Index(Name=\"PlaysFor_YearPosition\")]\n\tpublic string Position { get; set; }\n}\n\n[Node(Label=\"Person:Player\")]\npublic class Player : Person {\n  [Index(Label=\"Player\")]\n  public string Postion {get; set;}\n}\n```\nExample creates 3 Indexes (all range indexes by default):\n\t1. Relationship Range Index with default name **idx_PlaysFor_Year**\n\t2. Relationship Range Index with name **PlaysFor_YearPosition**\n\t3. Node Range Index with name **idx_Player_Position**\n\n\n### Defining your domain schema (RELATIONSHIPS)\n\n#### Identifying Relationships\nAnnotate the class with a RelationshipAttribute (optionally provide a Type, defaults to the class name in proper format).\n```csharp\n[Relationship]\npublic class PlaysFor {}\n\n[Relationship(Type=\"PLAYS_FOR\")]\npublic class Class1 {}\n```\nResults for both are `()-[:PLAYS_FOR]-()`\n\n### Defining your domain schema (NODES)\n\n#### Identifying Nodes and their Node Key\nAnnotate the class with a NodeAttribute (or it can also default to the class name)\n```csharp\n[Node(Label = \"Person\")]\npublic class Class1 {}\n\npublic class Person {}\n\n[Node]\npublic class Person {}\n```\nAnnotate the properties that make up the Node Key\n```csharp\npublic class Car {\n  [NodeKey]\n  public string Make { get; set; }\n\n  [NodeKey]\n  public string Model { get; set;}\n}\n```\n\nName your NodeKey; useful in cases of existing constraints or your project uses a specific naming convention. \nThe default is nk[firstLabel].\n```csharp\n[Node(Label=\"Car:Vehicle\", NodeKey=\"nkCar\")]\npublic class Car {\n  [NodeKey]\n  public string Make { get; set; }\n\n  [NodeKey]\n  public string Model { get; set;}\n}\n```\n\n#### Using Shared (or inherited) Node Keys\nIf you want to differentiate between 2 subclasses of an object but they are going to share the same node key, defined by the super class.\nWe can do something like this.\n```csharp\npublic class Person {\n  [NodeKey]\n  public string FirstName { get; set; }\n\n  [NodeKey]\n  public string LastName { get; set;}\n}\n\n[Node(Label=\"Person:Coach\")]\npublic class Coach : Person {\n  public int YearStarted {get; set;}\n}\n\n[Node(Label=\"Person:Player\")]\npublic class Player : Person {\n  public string Postion {get; set;}\n}\n```\nBoth players and coaches have a name; players can be coaches, and vice versa. Either way, this keeps our data clean preventing a person from having 2 records in the system.\n\n## SchematicNeo4j.Extensions\nThere are a few provided extensions that we can take advantage of when using the CustomAttributes.\nAssume the following Vehicle definition:\n```csharp\npublic class Vehicle {\n  [NodeKey]\n  public string Make { get; set; }\n\n  [NodeKey]\n  public string Model { get; set;}\n\n  [NodeKey]\n  public string ModelYear { get; set; }\n\n}\n```\n\n### We can get the Label by:\n```csharp\n// for a type\nvar theLabel = typeof(Vehicle).Label();\n```\n\n### We can get the Node Key properties by:\n```csharp\n// for a type\nList\u003cstring\u003e vehicleNodeKey = typeof(Vehicle).NodeKey();\n```\n\n### We can get the Node Key Name by:\n```csharp\n// for a type\nstring vehicleNodeKeyName = typeof(Vehicle).NodeKeyName();\n```\n\n\n## Using SchematicNeo4j.Schema.Initialize\nOnce we have our domain models identified we can use the `Schema` methods to put it into the graph. You can pass in either an entire assembly, a list, or a single Type.\nThis will create the indexes for both entity types, node and relationship.\n```csharp\n// Pass an Assembly and driver\nSchematicNeo4j.Schema.Initialize(assembly:Assembly.GetAssembly(typeof(DomainSample.Person)), driver);\n\n// Pass a list of domain types\n  // Get this assembly\n  Assembly a = Assembly.GetExecutingAssembly();\n  // Limit to a specific namespace.\n  var listOfTypes = a.ExportedTypes.Where(t =\u003e t.Namespace == \"MyExecutingThing.MyDomain\").ToList();\n  SchematicNeo4j.Schema.Initialize(listOfTypes, driver);\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdfrenchman%2Fschematica-dotnet-neo4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmdfrenchman%2Fschematica-dotnet-neo4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdfrenchman%2Fschematica-dotnet-neo4j/lists"}