{"id":21518111,"url":"https://github.com/okanok/grom","last_synced_at":"2026-05-06T22:37:03.136Z","repository":{"id":50680440,"uuid":"497300969","full_name":"okanok/grom","owner":"okanok","description":"A .NET graph database object relational mapper","archived":false,"fork":false,"pushed_at":"2022-10-23T15:27:13.000Z","size":723,"stargazers_count":2,"open_issues_count":9,"forks_count":0,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-07-25T18:19:02.407Z","etag":null,"topics":["dotnet","dotnetcore","graphdatabase","neo4j","orm"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/okanok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-28T11:42:02.000Z","updated_at":"2024-11-28T10:41:35.000Z","dependencies_parsed_at":"2023-01-20T12:19:54.767Z","dependency_job_id":null,"html_url":"https://github.com/okanok/grom","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/okanok/grom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okanok%2Fgrom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okanok%2Fgrom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okanok%2Fgrom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okanok%2Fgrom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/okanok","download_url":"https://codeload.github.com/okanok/grom/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okanok%2Fgrom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32715367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T19:35:05.142Z","status":"ssl_error","status_checked_at":"2026-05-06T19:35:03.996Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["dotnet","dotnetcore","graphdatabase","neo4j","orm"],"created_at":"2024-11-24T00:50:08.376Z","updated_at":"2026-05-06T22:37:03.123Z","avatar_url":"https://github.com/okanok.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Grom\nGrom, a .NET graph database object relational mapper.\n\nGrom is an easy to use, low config ORM that lets you map your C# classes to nodes and relationships in various graph databases.\nThis project is currently not production ready as it's still in beta. Version 1.0 is expected to release in Q4 2022. \n\nSince this project is open source and currently only worked on by the maintainer a 'beta' phase was needed in which a pre-production version is released so bugs can be found and fixed and important missing features can be requested before an actual production ready version is released.\n\nFeel free to try it out and if some feature is missing don't hesitate to open an issue!  \n\n# Quick start\n\n## Connecting Grom to your database\n\nConfiguring Grom is easy, it only requires a database connection to be given to GromGraph.CreateConnection(...). You don't need to instantiate this class or call it anywhere after running CreateConnection once.\n\n### Neo4J\nTo configure Grom for Neo4J simply use:\n```\nGromGraph.CreateConnection(GraphDatabase.Driver(\"bolt://localhost:7687\", AuthTokens.Basic(\"neo4j\", \"test\")));\n```\nAny valid instance of Neo4J IDriver can be passed, so you are not restricted to username/password authentication.\n### Gremlin Server\nTo configure Grom for any database that has Gremlin Server running use:\n\n```\nvar gremlinServer = new GremlinServer(\n    hostname: \"localhost\",\n    port: 8182,\n    username: \"root\",\n    password: \"test\"\n);\ngremlinClient = new GremlinClient(\n    gremlinServer: gremlinServer\n);\n\nGromGraph.CreateConnection(gremlinClient);\n```\nSimply provide any valid instance of GremlinClient to GromGraph.CreateConnection() and Grom will take care of the rest.\n\n## Mapping a class\nTo map a class as a node you have to do two things: inherit from EntityNode and annotate each property you want to map with NodeProperty. Grom does also require an empty constructor for all nodes.\n\nA mapped class can be as simple as:\n```\npublic class Person : EntityNode\n{\n    [NodeProperty]\n    public string Name { get; set; }\n\n    [NodeProperty]\n    public int Age { get; set; }\n}\n```\nCurrently integer, boolean, string, float, long, DateTime and DateOnly are supported.\n\n## Persisting a node\n\nTo persist a node simply call Persist() on any of your objects that inherit from EntityNode.\n```\nvar personNode = new Person(\"John\", 25);\nawait personNode.Persist();\n```\nGrom is fully asynchronous so make sure you await when required. \n\n## Updating a node\n\nUpdating a node is also done by calling Persist(). Grom will figure out if the node is allready created or not. \n```\nvar personNode = new Person(\"John\", 25);\nawait personNode.Persist();\n\npersonNode.Age = 30;\nawait personNode.Persist();\n```\nDo note that Grom only knows that a node exists if you have called Persist() on it or have retrieved it with Retrieve. It wont check if a node exists with the same properties in the database! \n\n## Deleting a node\n\nA node can be deleted by calling DeleteNode().\n```\nawait personNode.DeleteNode();\n```\nThe actual object in your code will still exist but the node and all its relationships to other nodes will be deleted in the database.\n\n## Retrieving a node\n\nNodes can be retrieved using Retrieve\\\u003cT\u003e. Nodes can be filtered by simply giving a lambda function that has a single parameter (the root node) and returns a boolean. Grom turns the lambda function into a query for you.\n```\nvar personNode = await Retrieve\u003cPerson\u003e\n    .Where(p =\u003e p.Name == \"John\")\n    .GetSingle();\n```    \nBoolean operators such as \u0026\u0026, ||, !, ==, !=, \u003e, \u003c, \u003e= and \u003c= are supported. Properties can be compared to constants, variables, method calls with no parameters and properties or fields in objects. Do note however that Grom can't turn everything a lambda can do into a query. Try to keep the lambda simple.\n\n## Relationships\n\nFor now only directed relationships are supported. Release 1.0 will also include support for undirected relationships.\n\nTo define a relationship between nodes we first need to create a relationship entity. The entity needs to inherit from RelationshipBase and needs an empty constructor. Each property you want to map can be annotated with RelationshipProperty. A relationship entity will look something like this:\n```\npublic class Knows : RelationshipBase\n{\n    [RelationshipProperty]\n    public int ForYears { get; set; }\n\n    public Knows()\n    {\n    }\n\n    public Knows(int forYears)\n    {\n        ForYears = forYears;\n\n    }\n}\n```\nTo define a relationship between nodes simply add a new property with type RelationshipCollection. This collection needs two arguments: a relationship type and a target node type. \n```\npublic class Person : EntityNode\n{\n    [NodeProperty]\n    public string Name { get; set; }\n\n    [NodeProperty]\n    public int Age { get; set; }\n\n    public RelationshipCollection\u003cKnows, Person\u003e knownPeople { get; set; } = new();\n\n    public Person()\n    {\n    }\n\n    public Person(string name, int age)\n    {\n        Name = name;\n        Age = age;\n    }\n}\n```\n\nA relationship is added by adding an item to this collection: \n```\nvar person1 = new Person(\"John\", 25);\nvar person2 = new Person(\"Doe\", 26);\nperson1.knownPeople.Add(new Knows(5), person2);\nawait person1.Persist();\n```\nCalling Persist() will, in adition to the node, also persist or update any descendant nodes and relationships. Updating works the same way as with nodes, change the property and call Persist() again on any ancestor node.\n\nTo delete a relationship you can use the Remove, RemoveAt or RemoveRange methods on RelationshipCollection. They work the same as in a List\\\u003cT\u003e. \n\n## Supported Databases\n\nCurrently Grom supports Neo4J and any database with Gremlin Server \u003e= 3.4.0.\n\nGrom's test suite tests against the following databases:\n* Neo4J\n* OrientDB\n\n# More info\n\n## Docs\n\nOur docs can be found [here](https://okanok.github.io/grom/)\n\n## Contribute \u0026 Bugs\n\nGrom is open source so feel free to checkout (pun intended) [the repo](https://github.com/okanok/grom) to see the code, features being worked on and maybe even to create a PR yourself! We also have an [issue board](https://github.com/okanok/grom/projects/1) to have a nice overview of the issues we have and the ones being worked on. Bugs can be reported on the discussions page [here](https://github.com/okanok/grom/discussions).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokanok%2Fgrom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fokanok%2Fgrom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokanok%2Fgrom/lists"}