Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for mapping columns to nested object properties #815

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jasonmcgraw
Copy link

@jasonmcgraw jasonmcgraw commented Mar 5, 2019

Current functionality does not allow the user to select and map columns to nested object properties of the return type when using the Query function.

This change will allow the user to alias a column as NestedObject.PropertyName, which will instantiate the NestedObject (if no default value) and assign the value of the column to the specified PropertyName of the NestedObject.

Example:
Given the table structure and DTO

//Table
class Foo
{
	public int Id { get; set; }
	public int FooReferenceId { get; set; }
}
//Table
class FooReference
{
	public int Id { get; set; }
	public string Name { get; set; }
}

//DTO
class FooModel 
{
	public int Id { get; set; }
	public int FooReferenceId { get; set; }
	public FooReference FooReferenceProperty { get; set; }
}

Current implementation would force us to populate the nested object FooReferenceProperty and its properties by combining multiple queries and in memory assignment like so:

string fooQuery =
	 " select" +
	 " fooTable.Id as 'Id'," +
	 " fooTable.FooReferenceId as 'FooReferenceId'" +
	 " from Foo as foo" +
	 " join FooReference fooReference on foo.FooReferenceId = fooReference.Id" +
	 " where foo.Id = 1";
var fooResult = db.Query<FooModel> (fooQuery);

var fooReferenceQuery = 
	 " select" +
	 " fooReference.Id as 'Id'," +
	 " fooReference.Name as 'Name'" +
	 " from Foo as foo" +
	 " join FooReference fooReference on foo.FooReferenceId = fooReference.Id" +
	 " where foo.Id = 1";
var fooReferenceResult = db.Query<FooReference> (fooQuery);

foreach (var item in fooResult)
{
	item.FooReferenceProperty = fooReferenceResult.FirstOrDefault (x => x.Id == item.FooReferenceId);
}

Doing this can become very cumbersome, especially when several nested objects are involved.

This modified implementation of ExecuteDeferredQuery will allow us to populate the nested object FooReferenceProperty and its properties with just a single Query call:

string fooQuery =
	 " select" +
	 " fooTable.Id as 'Id'," +
	 " fooTable.FooReferenceId as 'FooReferenceId'," +
	 " fooReference.Id as 'FooReferenceProperty.Id'," +
	 " fooReference.Name as 'FooReferenceProperty.Name'" +
	 " from Foo as foo" +
	 " join FooReference fooReference on foo.FooReferenceId = fooReference.Id" +
	 " where foo.Id = 1";
var fooResult = db.Query<FooModel> (fooQuery);

Note: Mapping will only be valid to the nested objects of the root object. This change does not support mapping to nested objects of nested objects.

…s. Add test fixture to to assert correct mappings.
@cherron-aptera
Copy link
Contributor

This looks really slick! Nice work on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants