This project is read-only.

Accessing Data

Topics: Customizing Orchard, General, Writing modules
Jun 8, 2011 at 8:43 PM

I  have three main questions about accessing the data in the database using Orchard.

1) How do you access a specific row in your database from the code ?


2) How do you create a module in which you field are correctly link to the database. I tried building the module simpleCommerce. The new module is showed in my administration page but the sku and the price fields aren't seem to be connected to the database. When I type in values and save, nothing is written in the database. So if you have another tutorial which I could base on.


3) Is there a way, in a module, to get the entire list of a table from the database ? I want to be able to populate a list and show this to the user. Is there also a way to get a list of a table data from many different table (in separate list) ? because it seems Orchard has been designed to work only on one module at a time.

Jun 9, 2011 at 6:15 AM

1) You can use IRepository<TPART> and query for what you need. Or you can use ISessionLocator to give you access to the current NHibernate session and do everything that NHibernate allows, and if you still want more power you can probably access the DbConnection instance in NHibernate and perform SQL queries.

2) Have you added a ContentHandler and set the Filter.Add(Storage.For<IRepository<OfYourPart>>()) ?

3) Orchard has been designed to work with Content Items. A content item is made up of ContentParts, and ContentFieds. ContentPart has a Record, which maps to a table in the DB. ContentField has a storage, the storage saves tha data as XML in the ContentFieldTable ( not sure about the table name ).

If you want the entire list of db tables, than you're probably required to use 1) NHibernate session directly or 2) DbConnection associated with NH session and execute a Select * from INFORMATION_SCHEMA where TYPE='u'. You can find the query online since it's pretty basic. I don't know what you need to execute on SQL CE.

Jun 9, 2011 at 3:35 PM

Thanks for answering !

1) But how do you use IRepository<TPART> and ISessionLocator ? Is there a tutorial somewhere for that ? The only one I've found so far are on MVC pattern but what they say don't always compile on Orchard. I don't think i need to send sql query. I want a simple row of data.


2) Yes I did. I followed thoroughly Orchard's tutorial (The one about writing a SimpleCommerce module) but it still doesn't work.


3) I didn't want something really fancy. I just want to be able to do a king of "select * from table" on 2 or tree tables and show the result.


Jun 9, 2011 at 3:48 PM

First, see the following documentation which covers some common data access scenarios:

For the code you've written that doesn't work, it might help if you post your code here and maybe we can see what the problem is!

Jun 9, 2011 at 5:44 PM
Edited Jun 9, 2011 at 5:45 PM

In your controller, or driver you just set a dependency on the controller for IRepository<MyRecord> ( sorry I wrote TPart there :P ). If you don't have a class extending Record, then you need to use ISessionLocator. There is no documentation AFAIK, you just get the source and search for it in the Solution. You should see how the actual Repository implementation uses it.

It should be pretty straight forward, ISessionLocation gives you a property that contains the current NHibernate session. If you don't have an entity defined in a namespace ending with Records or Models then FluentNHibernate will not know it needs to pick it up, and you'll have to fall back to HQL queries.

However if you are following the standard way, that is writing a Record, and a Part. And having the Part added to a ContentType. Then, you should be able to just use the ContentManager.Query<TPart>, where TPart is the concrete type you've written. You should probably browse through the documentation a bit more, and have a look at the Blog module.


Jun 9, 2011 at 7:15 PM

The thing is; it's a whole module so there are a lot of different files. Isn't a way to enclose file on this forum ? But anyway the code I put is the exact same thing as writtent in this tutorial:


Thanks for your tutorial. I am going through it. Hope I find what I need.

Jun 10, 2011 at 8:49 PM

I went through the tutorial. It's really useful for teaching how to create related table on Orchard but I didn't find what I was looking for. I just want to be able to access a table and get all the row from that table but the tutorial doesn't show how to do that.


Using IRepository seems a good idea. How do you create and use a IRepository dependency ? Do you have a snippet of code I could base on ?

Jun 10, 2011 at 9:29 PM

You don't have to create anything except the record class & migration. Just get a dependecy to IRepository<YourRecordType> injected into your class and we'll build one for you.

Jun 10, 2011 at 9:35 PM

What do you me by "we" ? You want me to send you my model and migration code ? By injecting a dependency do you mean creating a field of tye IRepository in my model class ?

Jun 10, 2011 at 9:41 PM

No :) You will still have to write your own code. What I mean is that just by taking a dependency on IRepository<Something>, the framework will provide an implementation of the repository.

Jun 10, 2011 at 9:44 PM

Lol okay. And where do I inject that dependency ? In my controller ? Or Driver ?

Jun 10, 2011 at 9:47 PM

Wherever you need to use it. That would typically be your controllers and drivers, yes.

Jun 10, 2011 at 9:59 PM

Where do I get an instance of the object ?

Jun 11, 2011 at 1:32 AM

What object?

Jun 11, 2011 at 11:31 AM

You inject into your constructor. So here's an example on a controller:

public class MyController : Controller {

    private readonly IRepository<MyRecord> _myRecordRepository;

    public IOrchardServices Services { get; set; }

    public MyController(
        IRepository<MyRecord> myRecordRepository,
        IOrchardServices services
    ) {

        _myRecordRepository = myRecordRepository;
        Services = services;


So the constructor will automatically get called with instances of the objects, you don't need to worry about it.

Jun 13, 2011 at 4:26 PM

Okay I got an instance of the IRepository but it throws an error each time I use it. For instance: It throws the following error on the call of the method "create":


Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:

Line 35:         {
Line 36:             get { return Record.Path; }
Line 37:             set { Record.Path = value; }
Line 38:         }
Line 39: 

Here's the code I put in my controller:


Themed ]


public class HomeController :




private readonly IRepository<FileU

> _myRecordRepository;


public IOrchardServices services { get; set

; }


public HomeController(IRepository<FileU

> myRecordRepository,





_myRecordRepository = myRecordRepository;



.services = services;



//ListU listFile = new ListU();


public ActionResult




new FileU { Path = "C:\\Salut", Name = "Essais.txt", Tag = ""



return View("UploadModule"






Here's my FileU.cs code:






















class FileURecord :





//public virtual int ID { get; set; }



public virtual string Path { get; set

; }



public virtual string Name { get; set

; }



public virtual string Tag { get; set

; }




public class FileU : ContentPart<FileURecord







public string Tag




get { return

Record.Tag; }



set { Record.Tag = value

; }







public string





get { return

Record.Name; }



set { Record.Name = value

; }








public string





get { return

Record.Path; }



set { Record.Path = value

; }





Jun 13, 2011 at 7:40 PM

The problem there is that you're implementing a ContentPartRecord but trying to access it like an ordinary (non-content) record.

These are the two distinctions:

- ContentPartRecord is used when you have data and functionality that you want to add to content items, via a ContentPart. You cannot use IRepository to access content parts - you have to go through IContentManager.Get(...) or IContentManager.Query(...) to retrieve the whole content item. You can perform querying on your ContentPartRecord using Where<MyContentPartRecord>(...).

- For all other data access, you implement your model as a POCO class, and say if it were called SomeModelRecord you'd use IRepository<SomeModuleRecord> to access the table directly. The ContentPart<TContentPartRecord> pattern is only for content parts, for any other database access you just deal with the record/model class directly.


Jun 13, 2011 at 7:54 PM

Which is the best to use ? I want to build a module allowing the administrator to enter file and show it to users depending on their rights. I don't quite understand the difference between a content part, a content Item and a widget.

Jun 13, 2011 at 8:04 PM

Does it make sense to add this to existing content types? If yes, make a part. If no, make a plain record.

Jun 13, 2011 at 8:27 PM

I think I will make it a record. It's strange because the code I wrote was based on the simpleCommerce module in Orchard tutorial. I have never been able to make it work though. Maybe that's why it didn't work. I inherited from the wrong class. So how do I implement POCO class ? In which package is this ?

Jun 13, 2011 at 8:29 PM

Just use that record class everywhere and don't inherit from ContentPartRecord. Don't implement a part. That's it. Make everything virtual and have an Id property.

Jun 13, 2011 at 10:51 PM
le_programmeur wrote:

Which is the best to use ? I want to build a module allowing the administrator to enter file and show it to users depending on their rights. I don't quite understand the difference between a content part, a content Item and a widget.

Content Item: A piece of content, composed of many Content Parts

Content Part: A chunk of functionality, business logic, and templates - it can be attached to any Content Types which are used to define actual Content Items.

Widget: Actually just a Content Item, with a special setting of Stereotype="Widget" (vs "Content" for a normal item), and also a Content Part called WidgetPart. A content type matching both those criteria can be added to layout zones, via the Layers system.

Hope that helps :)

Now; just regarding the module you're building (a simple Document Management system if I understand correctly). You could perhaps save yourself quite a bit of time by using some existing modules! Firstly, there's Piotr's Content Authorization system which allows you to apply authorisation rules for viewing content. Then, there's a project I'm working on called Media Garden - it improves on Orchard's basic media functionality, by creating each uploaded file as a proper Content Item complete with its own page/URL, whatever other parts you want to add, and an appropriate viewer for the type of file - in the case of binary document files this would just be a download link (although you could add other types of viewers for specific formats). Combined with Piotr's security system this would easily allow you to restrict who can view each file. Finally, there's a module I'm working on called Quanta, which is a system for granting users and groups of users specific roles over individual items.

Actually I was going to be implementing a proper integration between all three of those modules anyway, so yes what you'd have is a roles-based document management system. If you wanted to work with me on that, it could be fully working very soon - the vast majority of the work is already there, and I know there are some particularly tricky aspects to what you're doing!

Sep 26, 2011 at 12:49 PM

@sharpoverride : you are saying you can  "probably access the DbConnection instance in NHibernate and perform SQL queries"... how can you do that?

I'm always getting "No CurrentSessionContext configured (set the property current_session_context_class)!" error when trying to access 

_sessionFactoryHolder.GetSessionFactory().GetCurrentSession() ?