Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mdfrenchman/schematica-dotnet-neo4j
Neo4j.Schema: Tools to manage Neo4j Schema for a Domain Layer in .NET
https://github.com/mdfrenchman/schematica-dotnet-neo4j
csharp neo4j nuget-package schema
Last synced: 19 days ago
JSON representation
Neo4j.Schema: Tools to manage Neo4j Schema for a Domain Layer in .NET
- Host: GitHub
- URL: https://github.com/mdfrenchman/schematica-dotnet-neo4j
- Owner: mdfrenchman
- License: apache-2.0
- Created: 2019-05-19T21:25:41.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2024-04-25T19:56:33.000Z (8 months ago)
- Last Synced: 2024-11-29T00:23:25.667Z (24 days ago)
- Topics: csharp, neo4j, nuget-package, schema
- Language: C#
- Homepage:
- Size: 129 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SchematicNeo4j
A code-first approach to manage a consistent Neo4j graph schema for a domain layer that is defined in a .NET library.## For Developers
## New in version 5.0.0
- Relationship Attributes and Relationship Range Index.
- Added default and user specified names for indexes and constraints.
- Added NodeKeyName to the NodeAttribute, allowing for override of the default **nk{firstLabel}**.
- 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.#### Upcoming in the next minor release
- Index types other than Range Indexes.
#### Future change
- **potentially breaking change** Changing Extension and CRUD methods to a Fluent pattern to make method discovery and use easier.
- `typeof(Class1).Label()` makes autocomplete method discovery difficult. I'd like to simplify that.
- methods to list schema for export and comparison.### Using Range Index
Relationship 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.
The `Indexes.Create()` logic uses the class level attribute to differentiate between Relationship | Node.```csharp
[Relationship]
public class PlaysFor {[Index()]
[Index(Name="PlaysFor_YearPosition")]
public int Year { get; set; }
[Index(Name="PlaysFor_YearPosition")]
public string Position { get; set; }
}[Node(Label="Person:Player")]
public class Player : Person {
[Index(Label="Player")]
public string Postion {get; set;}
}
```
Example creates 3 Indexes (all range indexes by default):
1. Relationship Range Index with default name **idx_PlaysFor_Year**
2. Relationship Range Index with name **PlaysFor_YearPosition**
3. Node Range Index with name **idx_Player_Position**### Defining your domain schema (RELATIONSHIPS)
#### Identifying Relationships
Annotate the class with a RelationshipAttribute (optionally provide a Type, defaults to the class name in proper format).
```csharp
[Relationship]
public class PlaysFor {}[Relationship(Type="PLAYS_FOR")]
public class Class1 {}
```
Results for both are `()-[:PLAYS_FOR]-()`### Defining your domain schema (NODES)
#### Identifying Nodes and their Node Key
Annotate the class with a NodeAttribute (or it can also default to the class name)
```csharp
[Node(Label = "Person")]
public class Class1 {}public class Person {}
[Node]
public class Person {}
```
Annotate the properties that make up the Node Key
```csharp
public class Car {
[NodeKey]
public string Make { get; set; }[NodeKey]
public string Model { get; set;}
}
```Name your NodeKey; useful in cases of existing constraints or your project uses a specific naming convention.
The default is nk[firstLabel].
```csharp
[Node(Label="Car:Vehicle", NodeKey="nkCar")]
public class Car {
[NodeKey]
public string Make { get; set; }[NodeKey]
public string Model { get; set;}
}
```#### Using Shared (or inherited) Node Keys
If 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.
We can do something like this.
```csharp
public class Person {
[NodeKey]
public string FirstName { get; set; }[NodeKey]
public string LastName { get; set;}
}[Node(Label="Person:Coach")]
public class Coach : Person {
public int YearStarted {get; set;}
}[Node(Label="Person:Player")]
public class Player : Person {
public string Postion {get; set;}
}
```
Both 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.## SchematicNeo4j.Extensions
There are a few provided extensions that we can take advantage of when using the CustomAttributes.
Assume the following Vehicle definition:
```csharp
public class Vehicle {
[NodeKey]
public string Make { get; set; }[NodeKey]
public string Model { get; set;}[NodeKey]
public string ModelYear { get; set; }}
```### We can get the Label by:
```csharp
// for a type
var theLabel = typeof(Vehicle).Label();
```### We can get the Node Key properties by:
```csharp
// for a type
List vehicleNodeKey = typeof(Vehicle).NodeKey();
```### We can get the Node Key Name by:
```csharp
// for a type
string vehicleNodeKeyName = typeof(Vehicle).NodeKeyName();
```## Using SchematicNeo4j.Schema.Initialize
Once 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.
This will create the indexes for both entity types, node and relationship.
```csharp
// Pass an Assembly and driver
SchematicNeo4j.Schema.Initialize(assembly:Assembly.GetAssembly(typeof(DomainSample.Person)), driver);// Pass a list of domain types
// Get this assembly
Assembly a = Assembly.GetExecutingAssembly();
// Limit to a specific namespace.
var listOfTypes = a.ExportedTypes.Where(t => t.Namespace == "MyExecutingThing.MyDomain").ToList();
SchematicNeo4j.Schema.Initialize(listOfTypes, driver);```