A CMS like Orchard is, by definition, designed to store content. What differentiates content from other kinds of data is rather subtle. The way I would describe it is by saying that if you would put each instance of a kind of data on its own web page, if it would make sense to add comments to it, or tags, or ratings, then it is content and you can store it in Orchard using all the convenient composition options that it offers. Otherwise, it probably isn't and you can store it using somewhat simpler means that I will now describe. In one of the modules I wrote, Vandelay.ThemePicker, there is some configuration data for the module. That data is not content by the definition I gave above. Let's look at how this data is stored and queried. The configuration data in question is a set of records, each of which has a number of properties: public class SettingsRecord {
public virtual int Id { get; set;}
public virtual string RuleType { get; set; }
public virtual string Name { get; set; }
public virtual string Criterion { get; set; }
public virtual string Theme { get; set; }
public virtual int Priority { get; set; }
public virtual string Zone { get; set; }
public virtual string Position { get; set; }
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Each property has to be virtual for nHibernate to handle it (it creates derived classed that are instrumented in all kinds of ways). We also have an Id property.
The way these records will be stored in the database is described from a migration:
public int Create() {
SchemaBuilder.CreateTable("SettingsRecord",
table => table
.Column<int>("Id", column => column.PrimaryKey().Identity())
.Column<string>("RuleType", column => column.NotNull().WithDefault(""))
.Column<string>("Name", column => column.NotNull().WithDefault(""))
.Column<string>("Criterion", column => column.NotNull().WithDefault(""))
.Column<string>("Theme", column => column.NotNull().WithDefault(""))
.Column<int>("Priority", column => column.NotNull().WithDefault(10))
.Column<string>("Zone", column => column.NotNull().WithDefault(""))
.Column<string>("Position", column => column.NotNull().WithDefault(""))
);
return 1;
}
When we enable the feature, the migration will run, which will create the table in the database.
Once we've done that, all we have to do in order to use the data is inject an IRepository<SettingsRecord>, which is what I'm doing from the set of helpers I put under the SettingsService class:
private readonly IRepository<SettingsRecord> _repository;
private readonly ISignals _signals;
private readonly ICacheManager _cacheManager;
public SettingsService(
IRepository<SettingsRecord> repository,
ISignals signals,
ICacheManager cacheManager) {
_repository = repository;
_signals = signals;
_cacheManager = cacheManager;
}
The repository has a Table property, which implements IQueryable<SettingsRecord> (enabling all kind of Linq queries) as well as methods such as Delete and Create.
Here's for example how I'm getting all the records in the table:
_repository.Table.ToList()
And here's how I'm deleting a record:
_repository.Delete(_repository.Get(r => r.Id == id));
And here's how I'm creating one:
_repository.Create(new SettingsRecord {
Name = name,
RuleType = ruleType,
Criterion = criterion,
Theme = theme,
Priority = priority,
Zone = zone,
Position = position
});
In summary, you create a record class, a migration, and you're in business and can just manipulate the data through the repository that the framework is exposing. You even get ambient transactions from the work context.