Skip to content
Tuan Nguyen edited this page Oct 1, 2015 · 18 revisions

Welcome to the MagicalStorage wiki!

This is an alternative for Entity Framework, built to aim following objectives:

  • Support as many as possible types of persist storage (MSSQL, MySQL, DB2, Oracle, MongoDB, File, Memory, etc)
  • Support essential features which not (yet) available in Entity Framework, such as defining unique constraints
  • Super easy to use (even for developer without any database knowledge)

Features

  • Support MSSQL, MySQL, InMemory (usually for testing purpose during development of your system)
  • Support Unique attribute in Entity declaration (not available in Entity Framework)
  • Automatically generate database objects (tables, stored procedures)
  • TODO: support other types such as Oracle, MongoDB, DB2, etc

Known Issues

  1. One to many relation: DO NOT initialize value in constructor, otherwise it will not be loaded from persist storage
  2. One to one relation: property name must be the same class name

Full Documentation

Installation

Please view MagicalStorage and MagicalStorage SQL Repository on nuget.

Define Entity

Defining an entity is the same as doing in Entity Framework, except following:

  • Add [EntityType] attribute to class
  • Don't need to define Id property for one-to-one relation property
  • Can use [Unique] attribute to define unique constraints

Examples:

  • Define a standalone entity:
[EntityType]
public class MEAPUser
{
    public string Username { get; set; }
    public string DisplayName { get; set; }
}
  • Define one-to-one relationship:
[EntityType]
public class MEAPApplication
{
    public string ApplicationName { get; set; }
    // must be virtual and name the same as class name
    public virtual MEAPUser MEAPUser { get; set; }
}
  • Define one-to-many relationship:
[EntityType]
public class Platform
{
    public string PlatformName { get; set; }
    // must be virtual and List<T>
    public virtual List<MEAPApplication> Applications { get; set; }
}
  • Define unique constraints:
[EntityType]
public class MEAPUser
{
    [Unique]
    public string Username { get; set; }
}

In case a constraint is for more than one property, a string can be used to group those properties:

[EntityType]
public class MEAPApplication
{
    [Unique("UniqueAppName4EachUser")]
    public string ApplicationName { get; set; }

    // must be virtual and name the same as class name
    [Unique("UniqueAppName4EachUser")]
    public virtual MEAPUser MEAPUser { get; set; }
}

Define Repository

Repository is where entity data is actual stored.

Following repositories are available in this version:

  • MSSQLRepository
  • MySQLRepository
  • InMemoryRepository

To define repository, just create a new class instance:

var repository = new MSSQLRepository();

For ImMemoryRepository, no configuration is required, since all entity data is saved to memory (and lost when application is shutdown or restarted, so usually this repository is used for testing logic purpose).

For MSSQLRepository or MySQLRepository, connectionString must be defined in .config file. For example:

<connectionStrings>
    <add name="Connection" connectionString="Data Source=localhost;
         Initial Catalog=TestDB;User ID=sa;Password=sa@12345"
         providerName="System.Data.SqlClient" />
</connectionStrings>

Initialize Context

MSEntityContext is main class of this framework. Each context is associated with one and only one repository.

When defining a context, all types of entities must be specified to the context:

var context = new MSEntityContext(repository,
                     typeof(MEAPUser),
                     typeof(Platform),
                     typeof(MEAPApplication));

Save Data

Saving entity data is super easy, using MSEntityContext.Save function. It saves entity itself and all its relationships:

var platform = new Platform()
{
    PlatformName = "iOS",
    Applications = new List<MEAPApplication>()
};
var user = new MEAPUser()
{
    Username = "Admin"
};
var application = new MEAPApplication()
{
    ApplicationName = "TestApp",
    MEAPUser = user
};
platform.Applications.Add(application);

List<MSError> errors = null;
// Save all 3 platform, application and user entities
var savedEntity = context.Save(platform, out errors);
if (errors != null) {
    // TODO: error handling here
}

Delete Data

To delete an entity, just call MSEntityContext.Delete function:

context.Delete(savedEntity);

Remember that, it only deletes entity itself. All relationships will NOT be deleted.

Query Data

Query Data is still easy, just a little more complex than saving or deleting.

  • To get all entities (without any filter condition):
var list = context.GetAll<Platform>();
  • To filter entity by one of its property:
var condition = new MSCondition("Username", "Admin", MSCompareOperator.Like);
var list = context.Search<MEAPUser>(condition);
  • To filter entity by many properties:
var conditions = new MSConditions();
conditions.Add(("Username", "Admin", MSCompareOperator.Like);
conditions.Add(("DisplayName", MSCompareOperator.Exists);
var list = context.Search<MEAPUser>(conditions);
  • To return limit number of records:
var condition = new MSCondition("Username", "Admin", MSCompareOperator.Like);
var pageSetting = new MSPageSetting(50, 1); // first page and max = 50 records
var list = context.Search<MEAPUser>(condition, pageSetting);
  • To return sorted records:
var condition = new MSCondition("Username", "Admin", MSCompareOperator.Like);
var pageSetting = new MSPageSetting(50, 1);
pageSetting.AddSortInfo(new MSSortInfo("Username"));
var list = context.Search<MEAPUser>(condition, pageSetting);