Multiple models handled by the same interface

Hi all, I’ve just bought ServiceStack and I’m very newbie with all its best practises and concepts, so please be patient! :smiley:
This is my problem: I’ve got about 70+ tables in my MSSQL db that are defined by models like this:

 public class AN01_ANAGGEN
 {
        [AutoIncrement]
        public int AN01_IDANAGGEN { get; set; }

        [StringLength(50)]
        public string AN01_RAGSOCANAG { get; set; }

        [StringLength(100)]
        public string AN01_RAGSOCANAGEX { get; set; }

        [StringLength(50)]
        public string AN01_ALIAS { get; set; }

        [StringLength(10)]
        public string AN01_CAP { get; set; }

        [StringLength(2)]
        public string AN01_PROV { get; set; }
}

public class AN04_AZIENDE
{
        [AutoIncrement]
        public decimal AN04_IDAZIENDA { get; set; }

        public decimal AN04_IDLICENZA_LI01 { get; set; }

        public bool? AN04_FLGPREF { get; set; }

        [StringLength(50)]
        public string AN04_ALBO { get; set; }

        [StringLength(200)]
        public string AN04_NOTE1 { get; set; }

        [StringLength(200)]
        public string AN04_NOTE2 { get; set; }
}

I’d need to find the best way to re-use the same CRUD code for all these models without rewrite the same code as much as possible and in the “ServiceStack way”; for now, I ended up with this solution but I find it a nightmare… basically it’s the same code inside a switch! :frowning:

    [Route("/crud/{Table}")]
    [Route("/crud/{Table}/{Field}/{Value}")]
    public class CrudService
    {
        public string Table { get; set; }
        public string Field { get; set; }
        public string Value { get; set; }
    }

    public class CrudServices : Service
    {
        public object Get(CrudService request)
        {
            object result = null;

            switch (request.Table)
            {
                case "AN01_ANAGGEN":
                    if(!String.IsNullOrEmpty(request.Field) && !String.IsNullOrEmpty(request.Value))
                    {
                        result = Db.SqlList<AN01_ANAGGEN>("SELECT * FROM " + request.Table + " WHERE " + request.Field + " = " + request.Value);
                    } 
                    else 
                    {
                        result = Db.SqlList<AN01_ANAGGEN>("SELECT * FROM " + request.Table);
                    }
                    break;
                case "AN04_AZIENDE":
                    if (!String.IsNullOrEmpty(request.Field) && !String.IsNullOrEmpty(request.Value))
                    {
                        result = Db.SqlList<AN04_AZIENDE>("SELECT * FROM " + request.Table + " WHERE " + request.Field + " = " + request.Value);
                    }
                    else
                    {
                        result = Db.SqlList<AN04_AZIENDE>("SELECT * FROM " + request.Table);
                    }
                    break;
                default:
                    break;
            }

            return result;
        }

        public void Delete(CrudService request)
        {
            switch (request.Table)
            {
                case "AN01_ANAGGEN":
                    if (!String.IsNullOrEmpty(request.Field) && !String.IsNullOrEmpty(request.Value))
                    {
                        Db.ExecuteSql("DELETE FROM " + request.Table + " WHERE " + request.Field + " = " + request.Value);
                    }
                    break;
                case "AN04_AZIENDE":
                    if (!String.IsNullOrEmpty(request.Field) && !String.IsNullOrEmpty(request.Value))
                    {
                        Db.ExecuteSql("SELECT FROM " + request.Table + " WHERE " + request.Field + " = " + request.Value);
                    }
                    break;
                default:
                    break;
            }
        }
    }

Can someone please help me with an example? I’ve just started to use ServiceStack and I need the right hint to set up my entire project.
Thank you very much!

Hi, have you looked at AutoQuery? It sounds like it would be ideal for this where you’d just need to define Request DTO’s for each table you want to be able to query.

I’d never use a switch like this, I’d recommend instead to use individual services calling into the same generic base method, so each Service appears as individual Services in the metadata pages / auto-generated metadata services.

Hello mythz, is AutoQuery able to handle Post, Update and Delete events too? I did some tests and I can’t get it work…

As second solution, if I understand you right, you say to create a different service for each model… and then each service will call the same base method.
I’ve tried this too but I can’t figure out how to pass the model type (AN01_ANAGGEN or AN04_AZIENDE) to the base method, can you write me a bit of code to explain me this thing?
Thank you very much!

No AutoQuery only supports querying.

I just mean use normal C# to DRY code where possible, i.e. calling a common methods, extension methods, etc. Nothing to do with ServiceStack. I’d start with creating 2 different Services then work out what code you can share between them.

Here’s a Customer REST Crud Example outlining an approach I’d typically use, but honestly your solution is going to depend on how you intend to call them. An Application isn’t just going to expose and stick CRUD Services around each flat table unless this is for some kind of Generic UI, in which case then perhaps a single generic Service might be the way to go, but how you design your UI would impact how you’re going to design your Service.