Search code examples
c#.netdapperdapper-extensions

Dapper Extension: class with composite fields, mapped to an individual table


I have the following classes:

public class Publication
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Headline { get; set; }
    public DateTime Published { get; set; }
    public ProductContact Contact { get; set; }
}

public class ProductContact
{
    public string FullName { get; set; }
    public string JobTitle { get; set; }
    public string Email { get; set; }
}

And the table associated with this structure, "Publications", has all these fields (included the properties of ProductContact).

If I try to insert a Publication row (with the ProductContact information included) the program throws an exception:

System.NotSupportedException: The member Contact of type ProductContact cannot be used as a parameter value

So, I added a mapper to map out the ProductContact properties to fields in the Properties table:

  public PublicationMapper ()
    {
        TableName = "Publications";

        Map(x => x.Contact.FullName).Column("ContactFullName");
        Map(x => x.Contact.JobTitle).Column("ContactJobTitle");
        Map(x => x.Contact.Email).Column("ContactEmail");

        AutoMap();
    }

With this mapper I get the same exception.

Then, I added the ignore statement for the Contact field, to tell Dapper to not include this element in the insert statement

            Map(x => x.Contact).Ignore();

In this case, I get another exception:

System.Data.SqlClient.SqlException (0x80131904): Must declare the scalar variable "@FullName".

It indicates that Dapper is ignoring completely this property, and the mapping added in the previous step does not have effect.

Is there a way to map out the ProductContact properties to the table fields?

Thank you.


Solution

  • I don't think that this is possible with DapperExtensions.

    In one of their issues, they say

    Currently, we aren't planning to support nested objects. However, you can create your own Mapper that will allow for skipping over the nested object

    I have tried a variety of approaches and different mapping classes and can't get anywhere - I don't think that they support any way to map nested property values and to ignore the property itself (which, if not done, will result in "cannot be used as a parameter value" error).

    One approach would be to manually flatten your object into an anonymous class (as suggested by @juharr in a comment on your question), another approach would be to use something like AutoMapper to flatten your complex object into a flattened insert model.