datatypes using C#

One of the main features of Experience Management is the data services. Experience Management uses LINQ as the primary interface to query data, and all the data is 100% based on CLR types. Thus .NET types (interfaces) are also used when working and querying data.

The data layer in Experience Management totally abstracts the underlying stores like SQL Server or XML files away from the developer without sacrificing developer control. Instead of writing SQL statements or XML queries to get data, you will write LINQ statements.

All data items have one common interface they all inherit from: Composite.Data.IData. In Experience Management's terminology, an IData is what database developers would call a “table” or “schema”: an interface that inherits from IData is a definition of a data object which holds properties (name, type) and meta data like primary keys, foreign keys etc.

You can write a LINQ query without caring about the underlying store. If the underlying store is a SQL Server, then the LINQ query will be translated into an optimized SQL statement that gets the job done. And the same query, without any rewriting or even recompiling, can be used if the underlying store is XML – or any other kind of store for that matter.

For example, this is a query that works for any data store (SQL, XML, …)

using (DataConnection connection = new DataConnection())
{
var q = 
    from page in connection.Get<IPage>()
    where page.Title == "My Title"
    orderby page.UrlTitle
    select page;
}

Another example that will result in an inner join statement in the SQL database and in-memory object join when XML is used.

using (DataConnection connection = new DataConnection())
{
var q = 
    from page in connection.Get<IPage>()
    from pagetype in connection.Get<IPageType>()
    where page.PageTypeId == pagetype.Id
    orderby page.Title
    select new { page.Title, pagetype.Name };
}

The last example shows a query that will result in a left outer join in the SQL database and in-memory object join when XML is used.

using (DataConnection connection = new DataConnection())
{
var q = 
    from pagetype in connection.Get<IPageType>()
    join page in connection.Get<IPage>() on pagetype.Id equals page.PageTypeId into sub
    from s in sub.DefaultIfEmpty()
    select s;
}

In all these examples, IPage and IPageType are data interfaces that inherit from the base data interface IData. Below is a minimal example of a datatype in Experience Management:

[KeyPropertyName("Id")]
[DataScope(DataScopeIdentifier.PublicName)]
[ImmutableTypeId("{87122C34-E622-4e97-BD36-CBC398B862F9}")]
public interface IPerson : IData
{
    [StoreFieldType(PhysicalStoreFieldType.Guid)]
    [ImmutableFieldId("{172DD44C-426B-4812-834B-6B45366E78CB}")]
    Guid Id { get; set; }
    [StoreFieldType(PhysicalStoreFieldType.String, 249)]
    [ImmutableFieldId("{ADB24D3D-FA2A-496a-BBE9-91CFEB88336F}")]
    string Name { get; set; }
}

The class and field attributes are heavily used. The attributes are used as meta-information about the datatype – much like you have more information about SQL tables than just the table name and column name / type. This information is used throughout the system, from the low-level data store to the UI and is the basis of datatypes.

Important: These custom data interfaces must be defined in a Class Library project, built as an assembly (DLL) and placed in /Bin. You cannot create them in /App_Code.

If you were creating a new datatype using the datatype wizards in the Experience Management, restart the site by clicking Tools > Restart Server and then examine “/bin/Composite.Generated.dll” using a program such as.NET Reflector. You will notice that your data definition is actually of a CLR type now, with properties and attributes like, the one shown above.

To resume, all data schemas are defined as CLR types (interfaces) whether they are defined by Experience Management (like pages, users, templates etc.), you as a C# developer or users that use the visual data creation tools. And they are all accessible via LINQ.

When you are working with custom IData you typically only define an interface – concrete classes are generated by Experience Management automatically.