Dapper.NET composition using same table

.net composition dapper orm

Question

I have one table but I'd like to map it as a composition between two classes.

Suppose I have a Customer table with following fields: Id, Name, ExtraDataValue, ExtraDataDate.

class Customer
{
  public int Id {get;set;}
  public string Name {get;set;}
  public ExtraData Extra {get;set;}
}

class ExtraData
{
  public int Value {get;set;}
  public DateTime Date {get;set;}
}

What is the best way to query it and fill ExtraData inside Customer object?

Edit:

I'll extend the question to a more complex scenario, since XenoPuTtSs's answer solves the first one but will not work with this one.

Suppose now that I have a join to address table. The splitOn option will split the result to create ExtraData but will fail to split to create Address.

I see another problem using splitOn. We can't use Select * safely because if we alter table with more fields, we have to always remember to move split fields to bottom. Or we will always have to describe all fields in safe order in Select command.

Accepted Answer

splitOn:"Id, ExtraDataValue, Id"I believe this answers your newest rendition of the question. Now you have a join to address and it populates the address portion of your customer object.

class Customer
{
  public int Id {get;set;}
  public int Name {get;set;}
  public ExtraData Extra {get;set;}
  public Address Address{get;set;} 
}

class ExtraData
{
  public int Value {get;set;}
  public int Date {get;set;}
}

class Address {
    public string line1{get;set;}
}

using (var conn = DatabaseService.CreateConnection())
{
    var t = conn.Query<Customer, ExtraData, Address, Customer>(@"
    select 
        c.cust_num as Id,
        c.cust_name as Name,
        c.ex_data1 as Value,
        c.ex_date as Date,
        a.*
    from Customer c
     join Address a on c.addressid = a.addressid
    ",
     (cust, extra, address) =>
     {
         cust.Extra = extra;
         cust.Address = address;
         return cust;
     },
    splitOn:"Id, Value, Id");
    return t;
}

Popular Answer

I was just looking this up for myself. This is what I came up with, changed to your scenario.

class Customer
{
  public int Id {get;set;}
  public int Name {get;set;}
  public ExtraData Extra {get;set;}
}

class ExtraData
{
  public int Value {get;set;}
  public int Date {get;set;}
}

using (var conn = DatabaseService.CreateConnection())
{
    var t = conn.Query<Customer, ExtraData, Customer>(@"
    select 
        cust_num as Id,
        cust_name as Name,
        ex_data1 as Value,
        ex_date as Date
    from Customer
    ",
     (cust, extra) =>
     {
         cust.Extra = extra;
         return cust;
     },
    splitOn: "Value");
    return t;
}


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why