Question

I'm scratching my head trying to work out why petapoco's "Exists()" returns a false where it should return true. I use something like this to test:

A simple petapoco model:

[TableName("WorkLog")]
[PrimaryKey("Id")]
public class WorkLog : DefaultConnectionDB.Record<WorkLog>
{
     public int Id { get; set; }
     public Guid? Customer { get; set; }
     public Guid? Project { get; set; }
}

A database table with the same structure as above, filled with Id's and Customers (only nulls for Project).

Create a test object:

var x = new WorkLog {Id = 0, Customer = 'xxx-xxx-xxx...', Project = null}

Query if a the Worklog exists in DB, based on "Project":

var exist = db.Exists<WorkLog>("Project=@p", new { p = x.Project });

The result is "false" in this scenario. If I fill model, db and query with a Guid for Project it returns "true" like it should though.

So I guess this has something to do with null and DbNull comparison, but I can't seem to find the right place to dig. I've tried with a helper method for converting "null" to "DbNull" before query, but it still returns false.

Temporary solution:

Currently I've solved this by doing...

var exist = db.Exists<WorkLog>(x.Project == null ? "Project IS NULL" : "Project=@p", new { p = x.Project });

This now works as expected, but I'd rather the method could be called normally and still return the expected result.

Was it helpful?

Solution

The problem is more in the ADO.net side of thing than in PetaPoco. PetaPoco only create the Params and fill them with your values.

But, handling a null in the WHERE clause is tricky, as this MSDN article says:

Testing for Null

If a column in a table (in your database) allows nulls, you cannot test for a parameter value of "equal to" null. Instead, you need to write a WHERE clause to test whether both the column is null and the parameter is null. The following SQL statement returns rows where the LastName column equals the value assigned to the @LastName parameter, or whether both the LastName column and the @LastName parameter are null.

SELECT * FROM Customers
WHERE ((LastName = @LastName) OR (LastName IS NULL AND @LastName IS NULL))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top