Content parts with data in external db

Topics: Writing modules
Aug 31, 2015 at 11:46 AM
I cant find a clear example / tutorial for this question.

Say i want to create a content part, whose data is fetched / saved from an external sql server db.. And NOT the Orchard DB.

Can i create the content part definition in Orchard, and ensure that "something" acts as the data access layer? I dont want to have contentpartrecords duplicating data from my external DB, and storing in Orchard DB.

And when i compose content types, i dont want contentitems to be persisted in Orchard either.. Instead it goes to my custom DB.

It also feels cleaner to separate Orchard DB from my actual data currently stored in a separate DB, which could be a large RDBMS.

Please help with some examples. For example, how would an ecommerce site written on Orchard do it? Im sure its product catalog is on a separate DB. How would i create a "product" content type / content part, that does not store any data in Orchard DB.. Besides the "definition" of the part / type.
Sep 1, 2015 at 10:24 AM
Edited Sep 1, 2015 at 10:27 AM
I think a solution could be to implement the part as always, but don't define the storagefilter in the handler (and dont create migrations for the part). Instead, create a service that stores and retrieves your data to/from your other database. Then you can catch the handler events of the part to call the service and store it in your other db:
public class MyOtherDbAccessorService : IMyOtherDbAccessorService
{
    public void SaveData(MyCustomPart part) {
        // the logic for saving the data in your other db
    }

    public MyCustomPart RetrieveData(int contentItemId) {
        // the logic for retrieving the data from your other db
    }
}
handler:
public class MyCustomPartHandler
{
    private readonly IMyOtherDbAccessorService _accessorService;

    public MyCustomPartHandler(IMyOtherDbAccessorService accessorService) {
        _accessorService = accessorService;

        // Do NOT include Filters.Add(StorageFilter.For(myCustomPartRepository));
        // instead handle the events (not 100% sure which ones):
        OnUpdated<MyCustomPart>(UpdateCustomPart);
        OnLoaded<MyCustomPart>(LoadCustomPart);
    }

    public void UpdateCustomPart(Context context, MyCustomPart part) {
        _accessorService.SaveData(part);
    }

    public MyCustomPart LoadCustomPart(Context context, MyCustomPart part) {
        var data = _accessorService.RetrieveData(ctx.ContentItem.Id);
        // map data
        part.SomeProperty = data.SomeProperty;
        // ..
    }
}
Something like this might work :)
Sep 2, 2015 at 4:38 AM
Thx for the pointers.. Yes re-reading the documentation 15 times seems to point in the direction of contenthandlers too,

Im surprised there is no clear working tutorial for this.. This has to be the most common scenario in the real world.