Search code examples
c#generics.net-coredapperdapper-simplecrud

Error trying to insert generic with Dapper.SimpleCRUD


I'm trying to create a generic base class for my DataObjects like this :

public abstract class BaseDataObject<TDOType> where TDOType : class
{
    public static TDOType Get(Guid lObjectUUID, NpgsqlConnection conn)
    {
        return conn.Get<TDOType>(lObjectUUID);
    }

    public Guid Insert(NpgsqlConnection conn)
    {
        try
        {
            return conn.Insert<Guid, BaseDataObject<TDOType>>(this);
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

My inherited class :

[Table("mytable")]
public class MyTable : BaseDataObject<MyTable>
{
    [Key]
    [Column("mytableuuid")]
    public Guid MyTableUUID { get; set; }
    [Column("clientuuid")]
    public Guid ClientUUID { get; set; }

}

When I call this method from an inherited object, I am thrown with the following message :

42601: syntax error at or near ")"

When I look at the statement in the exception that is being passed, it looks like this :

{insert into "mytable" () values ()}

Even when I cast 'this', as follows, the result is the same :

try
{
    BaseDataObject<TDOType> q = this;
    return conn.Insert<Guid, BaseDataObject<TDOType>>(q);
}

It would appear that the generic function is not properly seeing the members of my inherited class. What am I doing wrong?


Solution

  • I do not have postgresql database; I used SQL Server. But that should not matter.

    Your problem is casting the generic object. Simply call the conn.Insert like below:

    return conn.Insert<Guid, TDOType>(this as TDOType);
    

    Note how I have cast the parameter to derived class than sending base class in to conn.Insert method. This way, SimpleCRUD can access the members of derived class.

    In your code, it is not able to see the members of derived class. Hence, it cannot generate the query.

    {insert into "mytable" () values ()}

    Look at the SQL query generated in your case as you post in question. It does not contain list of columns. Why? Because SimpleCRUD cannot see the properties of derived MyTable as you are sending in the base class BaseDataObject<TDOType>.


    I used following database script:

    CREATE TABLE [mytable]
    (
        [mytableuuid]       [UNIQUEIDENTIFIER] NOT NULL,
        [clientuuid]        [UNIQUEIDENTIFIER] NOT NULL
    )
    

    Following is the model declaration:

    [Table("mytable")]
    public class MyTable : BaseDataObject<MyTable>
    {
        [Key]
        [Column("mytableuuid")]
        public Guid MyTableUUID { get; set; }
        [Column("clientuuid")]
        public Guid ClientUUID { get; set; }
    
    }
    
    public abstract class BaseDataObject<TDOType> where TDOType : class
    {
        public static TDOType Get(Guid lObjectUUID, SqlConnection conn)
        {
            return conn.Get<TDOType>(lObjectUUID);
        }
    
        public Guid Insert(SqlConnection conn)
        {
            try
            {
                return conn.Insert<Guid, TDOType>(this as TDOType);//<--Just change this call
            }
            catch(Exception ex)
            {
                throw;
            }
        }
    }
    

    Following is how I call the Insert method:

    using(SqlConnection conn = new SqlConnection(@"connectionstring"))
    {
        MyTable myTable = new MyTable();
        myTable.MyTableUUID = Guid.NewGuid();
        myTable.ClientUUID = Guid.NewGuid();
        myTable.Insert(conn); 
    }