Roland
Roland

Reputation: 5234

Easiest way to use Dapper ORM

What is the easiest way to get the output of a Dapper ORM query into the data members of the class that provides the method for the query?

This is my code with a method A (ugly) and B (does not work):

public class MyLab_ClientRef
{
    public int UserId { get; set; }
    public string ClientId { get; set; }
    // ... more fields ...

    public bool GetUser(OracleConnection conn, int UserId, string ClientId)
    {
        bool Ok = false;
        IEnumerable<MyLab_ClientRef> QueryResultRecords =
            conn.Query<MyLab_ClientRef>(@"
                SELECT *
                FROM MyLab_ClientRef
                WHERE UserId   = :UserId
                  AND ClientId = :ClientId",
            new { UserId = UserId, ClientId = ClientId });
        if (QueryResultRecords.Count() == 1)
        {
            // Method A
            MyLab_ClientRef Rec = QueryResultRecords.First(); // works
            CopyRec(Rec, this);                               // ugly

            // Method B
            this = QueryResultRecords.First();            // avoids CopyRec, does not work

            Ok = true;
        }
        return Ok;
    }

    private static void CopyRec(MyLab_ClientRef CR_From, MyLab_ClientRef CR_To)
    {
        CR_To.UserId = CR_From.UserId;
        CR_To.ClientId = CR_From.ClientId;
    }
}

I like to keep the record definition close to the query that gets the record, but don't like to implement a CopyRec method for every table class this way.

Is there no better way to implement this? I tried to write this = ... but that is not possible.

How to write a method B that is better than method A?

Upvotes: 0

Views: 671

Answers (1)

Mrinal Kamboj
Mrinal Kamboj

Reputation: 11482

Following would not work:

this = QueryResultRecords.First();

Check following links for why:

Why can't I set "this" to a value in C#?

MSDN

As shown in the first link above, your best options remains that you return the MyLab_ClientRef from a given method, can make it static and use if for value or reference assignment, in this case either should yield same result

Check the following if this can be a cleaner implementation in your view:

public class MyLab_ClientRef
{
    public int UserId { get; set; }
    public string ClientId { get; set; }
    // ... more fields ...

    public static MyLab_ClientRef GetUser(OracleConnection conn, int UserId, string ClientId)
    {
        bool Ok = false;

        var QueryResultRecords =
            conn.Query<MyLab_ClientRef>(@"SELECT * FROM MyLab_ClientRef WHERE UserId = :UserId AND ClientId = :ClientId",new { UserId = UserId, ClientId = ClientId });

            if(QueryResultRecords.Any())
                return QueryResultRecords.First();
            else
                return null;        

    }  
}

It can be called as:

var newClient = MyLab_ClientRef.GetUser(conn, UserId,ClientId);

It would be preferred though is the connection object is local to a method and is use in the using clock

Upvotes: 1

Related Questions