Get Dto type and request fields in custom attribute

Hi I’m trying to implement an anti-overwrite function in my services to ensure that two users don’t overwrite the same db record at the same time; to do that I’ve added 2 fields in all my db tables that need this feature: the first one is for the lastchange-userid and the second one is for the lastchange-timestamp.

I’m writing a custom attribute that will be applied on the classes and methods that need this check before the request hits the end service.
The request itself contains the lastchange-userid and the lastchange-timestamp from the client… now, in my custom attribute, I need to get the type of my Dto and based on this type I need to perform a Select on my db to ensure the db and request values are the same… otherwise the request will be rejected.

I think to get the Dto type in the right way:

var dtoType = requestDto.GetType();

but I’m in trouble to use that type to query my db:

var db = req.TryResolve<IDbConnectionFactory>().Open();
var lastChange = db.Select<???>();

How can I solve this, please?

I don’t understand, you just specify the POCO Type of the table you want to query.

But why are you trying to select the Request DTO Type? Are you planning on creating a RDBMS Table for each Request DTO Type you have? Have you already created a table for each Request DTO Type?

Yes, I already have all my POCO Types for all my Db tables and I have a service for each of them… I have a 1:1:1 relation between my table <-> POCO <-> service.
Obviously not all these tables need a “last change check” so I’ve created this custom attribute to be applied on “their” services to perform the check and dry a bit the services.
I’m missing how to get the POCO Type of the table from the request Dto.

Still not clear if you have a table for each Request DTO, sounds very strange you’d create a table using the schema definition of each Request DTO, but either way there are Select API’s which let you specify a runtime Type, e.g:

var results = db.Select<TypeToSelectInto>(dtoType);
var results = db.Select<TypeToSelectInto>(dtoType, "Id = @Id", new { requestDto.Id });

But now you need to specify how the results should be returned, if all Request DTO’s share the same schema/base type you can select into that Type otherwise here are several options of how to retrieve data you don’t know the type of.

Thank you! I think that with:

db.Column<string>("SELECT LastName FROM DeptEmployee").PrintDump();

…I’ll solve my problem.

I’ve got just another question now… Is there a way to check if a param exists in my request and if it exists change its value?

I don’t understand the question, please provide an example.

Sorry, it could be a new question but it’s related with the previous one.
I need to overwrite a request param in my custom attribute before the request hits the service.
I’ve tried with:

public override void Execute(IRequest req, IResponse res, object requestDto)
{
    req.QueryString["MyParam"] = "my-new-value"; 
}

but it seems that the collection is “read-only”…

You can’t modify the QueryString, it holds the QueryString of the incoming request.
If you want to pass additional variables to your Service you can use IRequest.Items.

I understand…
My idea was to directly update the laschange-timestamp when the request passes through my RequestFilterAttribute so the service next should just save the entire request payload without I have to remember each time to save the value that the filter put in the Items list.

request.LastChange = Request.GetItem("LastChange");
Db.Update<Customer>(request);

I also need to check the request lastchange-timestamp is the same of the db one, to ensure nobody overwritten the record…
I’m a bit out of ideas on how implement this without rewrite the same code in every service… what is the best approach in your experience?

I’m having a really hard time trying to follow your solution, in that I don’t think I understand what your solution is, i.e. still don’t know whether or not you have a table per Request DTO as suggested in your original question - which isn’t something I’d consider.

From the feature description it sounds like you just want Optimistic Concurrency in which case I’d just be using the in-built support for RowVersion in OrmLite. Basically it works transparently where if the version of the record has changed since it was read it will throw an OptimisticConcurrencyException otherwise it will succeed.

Yes… I’m trying to do something similar as Optimistic Concurrency does… but I need something slightly different; I need to have a datetime instead of a unique string… and at the same time I need to update two fields in my tables: the user id of the last record change and its company id (it’s a shared multi-tenant db).
I need to do this operation on more or less 60 of my 78 tables db (as many as the services).
So I was thinking that using a RequestFilterAttribute would be the best way to do it… comparing the datetimes and changing the Dto params before pass them to the service… but as you told me, if I can’t change the request Dto in the filter it would become a bit messy.