Search code examples
servicestackautoquery-servicestackservicestack-autoquery

ServiceStack AutoQuery into custom DTO


So, I'm working with ServiceStack, and know my way around a bit with it. I've used AutoQuery and find it indispensable when calling for straight 'GET' messages. I'm having an issue though, and I have been looking at this for a couple of hours. I hope it's just something I'm overlooking.

I have a simple class set up for my AutoQuery message:

public class QueryCamera : QueryDb<db_camera>
{
}

I have an OrmLite connection that is used to retrieve db_camera entires from the database. this all works just fine. I don't want to return a model from the database though as a result, I'd like to return a DTO, which I have defined as another class. So, using the version of QueryDb, my request message is now this:

public class QueryCamera : QueryDb<db_camera, Camera>
{
}

Where the Camera class is my DTO. The call still executes, but I get no results. I have a mapper extension method ToDto() set up on the db_camera class to return a Camera instance.

Maybe I'm just used to ServiceStack making things so easy... but how do I get the AutoQuery request above to perform the mapping for my request? Is the data retrieval now a manual operation for me since I'm specifying the conversion I want? Where's the value in this type being offered then? Is it now my responsibility to query the database, then call .ToDto() on my data model records to return DTO objects?

EDIT: something else I just observed... I'm still getting the row count from the returned dataset in AutoQueryViewer, but the field names are of the data model class db_camera and not Camera.

enter image description here


Solution

  • The QueryDb<From, Into> isn't able to use your Custom DTO extension method, it's used to select a curated set of columns from the executed AutoQuery which can also be used to reference columns on joined tables.

    If you want to have different names on the DTO than on your Data Model, you can use an [Alias] attribute to map back to your DB column name which will let you name your DTO Property anything you like. On the other side you can change what property the DTO property is serialized as, e.g:

    [DataContract]
    public class Camera
    {
        [DataMember(Name = "Id")]        // serialized as `Id`
        public camera_id { get; set; }   // populated with db_camera.camera_id
    
        [DataMember]
        [Alias("model")]                 // populated with db_camera.model
        public CameraModel { get; set; } // serialized as `CameraModel`
    }