Home
Mapping Classes
Introduction
Mapping classes are classes annotated with the Frog.NET class annotations [Table]. They are object representations of any database output. For instance you would want to map the result of "SELECT * FROM Users" into a list of User instances. 1: [Table]
2: public class User
3: {
4: [PrimaryKey]
5: public long Id { get; set; }
6:
7: [Column]
8: public string Name { get; set; }
9: }
Using Frog.NET to fetch a database row, and map it to the User class defined above will produce the following SQL command: "SELECT [Id],[Name] FROM [User]"
Mapping classes are usually used to fetch from database tables, but they can instead be using database views, in which case they will only work for read-only scenarios. While in most situations you want your mapping class to be named like your table (or view), you can override this default behaviour by setting the Name parameter of the [Table] attribute.
With name overriding you also have the option of using two or more different mapping classes for the same table (or view).
1: [Table(Name="User")]
2: public class UserSimple
3: {
4: [PrimaryKey]
5: public long Id { get; set; }
6:
7: [Column]
8: public string Name { get; set;
9: }
10:
11: [Table(Name="User)]
12: public class FullUserInformation
13: {
14: [PrimaryKey]
15: public long Id { get; set; }
16:
17: [Column]
18: public string Name { get; set;
19:
20: [DateTime]
21: public DateTime Birthday { get; set; }
22: }
Entities with Children
In the world of databases you often come across one-to-many releations. Naturally most applications depends on this relational data, and not just simple data types. To accomodate this you can use the [RequiredDependency] attribute on you mapping classes. This allows you to implement late-fetching of data rows, when the application requires it. Note that Frog.NET does NOT magically load a full object graph like other O/R mappers - Instead you have to implement just-in-time fetching like in the example below. The [RequiredDependency] attribute instructs the framework to provide a base Repository upon the initialization of the entity object 1: [Table]
2: public class Person
3: {
4: [PrimaryKey]
5: public long Id { get; set; }
6:
7: [RequiredDependency]
8: public IRepository Repository { get; set; }
9:
10: [Column]
11: public IList<Child> Children
12: {
13: var result = Repository.GetWhere<Child>(Field.Equals("ParentId", this.Id);
14: return result.ToList();
15: }
16: }
As the example above indicates, you should never (due to performance) iterate over a list of persons and call Children property on each of them. This will result in Number_Of_Children + 1 database queries, potentially making your application painfully slow. If your application should need to fetch all children, you could instead implement a GetAllChildren() method on a PersonRepository.
If in doubt, you can use the log file to investigate exactly what queries has been executed.
