For Developer
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)
- 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
- One to many relation: DO NOT initialize value in constructor, otherwise it will not be loaded from persist storage
- One to one relation: property name must be the same class name
Please view MagicalStorage and MagicalStorage SQL Repository on nuget.
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; }
}
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>
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));
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
}
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 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);