sqlite-net icon indicating copy to clipboard operation
sqlite-net copied to clipboard

Added Fluent API

Open roygoode opened this issue 9 years ago • 15 comments

The changes made in this pull request allow tables to be created using a Fluent API with attribute-free objects (aka POCOs). This allows for cleaner separation of layers and aids dependency injection by not requiring references to sqlite-net to decorate model classes with attributes.

Example usage:

connection.BuildMapping<SampleEntity>()
		  .TableName("ExampleTable")
		  .PrimaryKey(x => x.Key)
		  .CreateTable();

connection.BuildMapping<SampleEntity2>()
		  .TableName("Users")
		  .PrimaryKey(x => x.Id)
		  .AutoIncrement(x => x.Id)
		  .ColumnName(x => x.PasswordHash, "Password")
		  .Unique(x => x.Username)
		  .CreateTable();

connection.BuildMapping<SampleEntity3>()
		  .TableName("Contacts")
		  .Index("ix_full", x => x.Name, x => x.Email, x => x.Telephone)
		  .PrimaryKey(x => x.Id, true)
		  .MaxLength(x => x.Email, 255)
		  .NotNull(x => x.Email)
		  .Ignore(x => x.SecretMessage)
		  .CreateTable();

Based on the following example plain model classes...

public class SampleEntity
{
	public string Key { get; set; }

	public string Value { get; set; }
}

public class SampleEntity2
{
	public int Id { get; set; }

	public string Username { get; set; }

	public string PasswordHash { get; set; }
}

public class SampleEntity3
{
	public int Id { get; set; }

	public string Name { get; set; }

	public string Email { get; set; }

	public string Telephone { get; set; }

	public string SecretMessage { get; set; }
}

Note: CreateTable() must be called to trigger the creation of the mapping and resulting table.

The additional code recycles existing functionality for creating table mappings from attributes.

roygoode avatar Apr 03 '17 21:04 roygoode

I was looking forward to this! Removing decoration from the classes and moving the sqlite dependency to where it is being used will be awesome 👍

RezaJooyandeh avatar Apr 16 '17 18:04 RezaJooyandeh

I made a change in #599 that is similar. That caches and allows custom building of TableMappings. I wonder if there is a way to combine the ideas. See the DefaultTableMapper. https://github.com/praeclarum/sqlite-net/pull/599/files?w=1#diff-e249207f2f9ac72b8e31b87d9be311e1R2523

The reason cached it was because I saw a lot of memory pressure, since most queries require the TableMapping. The reason I created the DefaultTableMapper was because in a couple cases I needed to do custom mappings against tables, where my object structure needed to have a hierarchy but my tables needed to be flat.

nberardi avatar Aug 08 '17 20:08 nberardi

Hello!

I really love this but would like to change a few things too.

I think the builder should make TableMappings and those can be sent to CreateTable. This would make calling CreateTablesAsync more palatable.

So the syntax would be something like:

var mapping = TableMapping.Build<SampleEntity3>()
		  .TableName("Contacts")
		  .Index("ix_full", x => x.Name, x => x.Email, x => x.Telephone)
		  .PrimaryKey(x => x.Id, true)
		  .MaxLength(x => x.Email, 255)
		  .NotNull(x => x.Email)
		  .Ignore(x => x.SecretMessage)
		  .ToMapping();
connection.CreateTable (mapping);

praeclarum avatar Aug 13 '17 04:08 praeclarum

Great work!

praeclarum avatar Aug 13 '17 04:08 praeclarum

Tracking issue is #422

praeclarum avatar Aug 13 '17 04:08 praeclarum

@praeclarum @RoyGoode what would it take to get this going? I started messing around with Roy's code based on your comments but this PR is from April has quite a bit of drift at this point.

Eonasdan avatar Aug 28 '17 20:08 Eonasdan

Looking forward to this feature

sunthx avatar Sep 04 '17 06:09 sunthx

Apologies to all in the delay in getting these updates in. I’ve spent pretty much the last 12 months working on non-.NET projects, but I’m back on Xamarin now for a new project. I will re-implement the Fluent API with the latest version and as per @praeclarum’s great suggestions.

roygoode avatar Jul 01 '18 17:07 roygoode

As promised, I've updated to the latest source, and re-applied the new Fluent API changes, and also updated according to @praeclarum's reviews.

Here is an update to the example usage:

var entity1 = TableMapping.Build<SampleEntity>()
		  .TableName("ExampleTable")
		  .PrimaryKey(x => x.Key)
		  .ToMapping();

var entity2 = TableMapping.Build<SampleEntity2>()
		  .TableName("Users")
		  .PrimaryKey(x => x.Id)
		  .AutoIncrement(x => x.Id)
		  .ColumnName(x => x.PasswordHash, "Password")
		  .Unique(x => x.Username)
		  .ToMapping();

var entity3 = TableMapping.Build<SampleEntity3>()
		  .TableName("Contacts")
		  .Index("ix_full", x => x.Name, x => x.Email, x => x.Telephone)
		  .PrimaryKey(x => x.Id, true)
		  .MaxLength(x => x.Email, 255)
		  .NotNull(x => x.Email)
		  .Ignore(x => x.SecretMessage)
		  .ToMapping();

connection.CreateTable(entity1);
connection.CreateTable(entity2);
connection.CreateTable(entity3);

// OR

connection.CreateTables(CreateFlags.None, entity1, entity2, entity3);

roygoode avatar Jul 02 '18 14:07 roygoode

I have created a fresh pull request #727 with a cleaner branch as my master was tracking the original master from circa April 2017 and has created diffs that look like a mess. The new pull request should be much easier to merge.

roygoode avatar Jul 02 '18 14:07 roygoode

this will be very helpful if this will be merged in the soonest possible time

ghost avatar Jul 15 '18 12:07 ghost

What is status on this pull request? This is a must have feature if you want to map third-party models.

rdvojmoc avatar Aug 18 '19 21:08 rdvojmoc

Is there any status update available?

Mrsevic avatar Nov 09 '20 20:11 Mrsevic

@Mrsevic I have merged and fixed current official and fluent api pull requests for testing, it seems ok. I'll try to use it in production.

But it's only in my fork (I'm not sure now if all the fixes are pushed to github)

michaldobrodenka avatar Nov 10 '20 07:11 michaldobrodenka

Trying to build out of @RoyGoode's changes. Anyone almost close to making it work?

lancecontreras avatar Apr 01 '24 21:04 lancecontreras