Creating a Domain entity
Domain entities provide a way to add your own tables to the Smartstore database. In this tutorial, you will add a simple notification system to your Hello World module.
Preparing the table
Table schema
A simple notification might have the following properties:
A unique identifier (
Id, type: number)An author, represented by the customer ID (
AuthorId, type: number)A timestamp (
Published, type: date-time)A message (
Message, type: string)
Here is what the table might look like:
1
543
2022-12-12 11:48:08.9937258
Hello World!
2
481
2022-12-13 19:02:55.7695421
What a beautiful day it is 😄
Create the Domain entity
Overview
The domain object is an abstract data structure that has all the properties of the entity it describes. Entity Framework automates the mapping between domain objects and database tables.
Specify the table name and the indexes using Code First Data Annotations and add the properties that represent your database columns.
// Outside the class.
// Specify your table name. By convention, the entity name is used.
[Table("TableNameInDatabase")]
// Declare an index.
[Index(nameof(PropertyName), Name = "IX_ClassName_PropertyName")]
// Inside the class.
// Define some columns.
public int ColumnA { get; set; }
public bool ColumnB { get; set; } = true;Implementation
Add the Notification.cs file to the new Domain directory and do the following
Specify the table name
Notification.Declare
AuthorIdandPublishedas indexes.Implement the abstract
BaseEntityclass.Add the
AuthorId,PublishedandMessageproperties.
Your Notification class should look something like this:
[Table("Notification")]
[Index(nameof(AuthorId), Name = "IX_Notification_AuthorId")]
[Index(nameof(Published), Name = "IX_Notification_Published")]
public class Notification : BaseEntity
{
public int AuthorId { get; set; }
public DateTime Published { get; set; }
[MaxLength]
public string Message { get; set; }
}This represents the Notification table with the three columns: AuthorId, Published and Message. The MaxLength attribute will truncate Message to the maximum supported length of strings allowed in a property. Because you will often search for notifications based on either AuthorId or Published, these are defined as indexes.
Create the Migration
To add the Notification table to the Smartstore database, you must create a migration. The migration framework creates the table at application startup. In this tutorial, you will only override the Up method of the abstract MigrationBase class.
Create the Migrations directory and add the migration class whose name includes the current date, YYYYMMDDHHMMSS_Initial.cs. Add the following attribute to each class
// Use the current date and time [YYYY-MM-DD HH:MM:SS]
[MigrationVersion("2022-12-14 10:34:22", "HelloWorld: Initial")]The class must inherit from the Migration base class to have access to the SQL database schema helper methods such as Create, Remove, or Update. You can now use these methods to check if the table already exists, and if it does not, to create it.
var tableName = "Notification";
if (!Schema.Table(tableName).Exists())
{
Create.Table(tableName);
}To add columns, set indexes, and specify primary keys, you can simply chain the following FluentMigrator methods:
WithColumn
Defines a new column.
WithIdColumn
Defines an id column that will act as the primary key.
You can define a column type (Boolean, Integer, String, Date, Currency, etc.) and declare it as (not) nullable, unique, a primary key, indexed, etc.
Create.Table(tableName)
.WithIdColumn()
.WithColumn(nameof(Notification.AuthorId))
.AsInt32()
.NotNullable()
.Indexed("IX_Notification_AuthorId")
.WithColumn(nameof(Notification.Published))
.AsDateTime2()
.NotNullable()
.Indexed("IX_Notification_Published")
.WithColumn(nameof(Notification.Message))
.AsMaxString()
.NotNullable();The class should look like this:
[MigrationVersion("2022-12-14 10:34:22", "HelloWorld: Initial")]
public class _20221214103422_Initial : Migration
{
public override void Up()
{
// The table name is taken from Domain->Attribute->Table
var tableName = "Notification";
if (!Schema.Table(tableName).Exists())
{
Create.Table(tableName)
.WithIdColumn() // Adds the Id property as the primary key.
.WithColumn(nameof(Notification.AuthorId))
.AsInt32()
.NotNullable()
.Indexed("IX_Notification_AuthorId")
.WithColumn(nameof(Notification.Published))
.AsDateTime2()
.NotNullable()
.Indexed("IX_Notification_Published")
.WithColumn(nameof(Notification.Message))
.AsMaxString()
.NotNullable();
}
}
public override void Down()
{
// Ignore this for now.
}
}Providing table access in modules
Now that you have the table set up, you need to give your module access to it. To access the table from a SmartDbContext instance you need to add the following two files:
Startup.cs in the root of your directory
SmartDbContextExtensions.cs in the Extensions directory (must be created)
Create the static SmartDbContextExtension class and add the following method:
public static DbSet<Notification> Notifications(this SmartDbContext db)
=> db.Set<Notification>();The Startup class inherits from the StarterBase class and contains the following lines:
public override void ConfigureServices(IServiceCollection services, IApplicationContext appContext)
{
services.AddTransient<IDbContextConfigurationSource<SmartDbContext>, SmartDbContextConfigurer>();
}
private class SmartDbContextConfigurer : IDbContextConfigurationSource<SmartDbContext>
{
public void Configure(IServiceProvider services, DbContextOptionsBuilder builder)
{
builder.UseDbFactory(b =>
{
b.AddModelAssembly(GetType().Assembly);
});
}
}Now you can access the entities stored in your table using the SmartDbContext.
var messages = await _db.Notifications()
.Where(x => x.Message.Length > 0)
.FirstOrDefaultAsync();Next steps
The following steps are included in the module code:
Add a configuration view. Configure the number of days to display a notification.
Display the notification as a widget. This way, you can place it anywhere you want in the store.
Add a new notification button. Let the current admin create a message.
Schedule a task to purge the table. This will increase database speed by removing old, unnecessary messages from your table.
Further ideas
There are many other things you can do with this module:
Add a Moderator
CustomerRoleand a separate view to allow certain users to create notifications.Add categories to your notifications. Display specific notifications on different pages.
Make your entities accessible through the Web API.
Conclusion
In this tutorial, you learned how to:
Adding a Table to the Smartstore Database
Create a migration for it
Extend
SmartDbContextwith your tables
Last updated
Was this helpful?