This is an implementation to make models to have navigation properties work like ORM does for us.
Over here we have navigation property on Addresses from Person and Person from Address based on PersonId and AddressId.
This is not recommended way to do in case of NoSql implementation but in case, if arises. I am also putting Id's as primary key which is not the native case with NoSql.
This is a mapping implementation of Person model, which would initialize Addresses property to automatically fill.
The implementation is done with the ToList projection which would fill data into memory on InitNavigation function call only.
The usage can be very simple now.
We just need to compose the query and get a single item, once that is retrieved we can have a call to InitNavigation to initialise navigation property.
This is just a concept of implementation which can be extended based on need like instead of generating mapping manually T4 can be used to generate those codes automatically.
What actually happens in ORM to make navigation properties work?
Entity Framework has proxy classes implementation to allow lazy loading and eager loading implementation. While creating proxy classes it also changes definitions for actual classes to make navigation properties work to get values based on Model's for navigation properties. Most of ORMs work in same fashion like Telerik DataAccess has enhancer tool which changes class definition at compile time to enable navigation properties.
In this implementation, we would retain the original class but we would have extension methods to allow initializing properties to have navigation proprieties work.
Let's first create desire model on which we need to implement. I am picking up simple one-to-many relationship example from Person to Address.
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int AddressId { get; set; }
public int PersonId { get; set; }
public string Street { get; set; }
public Person Person { get; set; }
}
Over here we have navigation property on Addresses from Person and Person from Address based on PersonId and AddressId.
This is not recommended way to do in case of NoSql implementation but in case, if arises. I am also putting Id's as primary key which is not the native case with NoSql.
This is a mapping implementation of Person model, which would initialize Addresses property to automatically fill.
public static class PersonMapping
{
public static Person InitNavigation(this Person model, IMongoDatabase mongoDB)
{
var relatedInfo = mongoDB.GetCollection<Address>("Address");
model.Addresses = relatedInfo.Find(add => add.PersonId == model.PersonId).ToList();
return model;
}
}
The implementation is done with the ToList projection which would fill data into memory on InitNavigation function call only.
The usage can be very simple now.
var mongoDb = new MongoClient("<connection string>").GetDatabase("<database>");
var personData = mongoDb.GetCollection<Person>(nameof(Person)).Find(per => per.PersonId == 1)
.FirstOrDefault().InitNavigation(mongoDb);
var person1addresses = personData.Addresses;
We just need to compose the query and get a single item, once that is retrieved we can have a call to InitNavigation to initialise navigation property.
This is just a concept of implementation which can be extended based on need like instead of generating mapping manually T4 can be used to generate those codes automatically.
Comments
Post a Comment