El Che
El Che

Reputation: 1321

Unique constraint on nullable in System.Data.DataColumn

In my database I have a table like this

table foo
int pk
int someFK NULL

with foreign key constraint on someFK and unique constraint on someFK. This means in the MySQL database that I have that unless I specify NULL in someFK, there has to be a row in the corresponding table of course. However, I can also have several rows with NULL in someFK even if the unique constraint is on.

In my code, I use System.Data namespace and do like this:

DataTable table = new DataTable("Foo");

DataColumn col = null;

DataColumn[] primaryKey = new DataColumn[1];

col = table.Columns.Add(FooPropertyName, typeof(int));
col.Unique = true;
col.AutoIncrement = true;
primaryKey[0] = col;
table.PrimaryKey = primaryKey;

col = table.Columns.Add(SomeFkPropertyName, typeof(int));
col.Unique = true;
col.AutoIncrement = false;

However, if I add two DataRows to my DataTable, and those two have different primary keys but both have DBNull on the someFK column, I get an error message Exception Type: System.Data.ConstraintException Exception Message: Column 'somefk' is constrained to be unique. Value '' is already present.

This is not what I expect, so I was wondering if someone knows how to get around this (without removing the unique property)

Upvotes: 1

Views: 3845

Answers (1)

M Afifi
M Afifi

Reputation: 4795

You need to tell DataTable null values are accepted.

col = table.Columns.Add(SomeFkPropertyName, typeof(int)); 
col.Unique = true; 
col.AutoIncrement = false; 
col.AllowDBNull = true;

More here AllowDBNull

Edit 1

You're correct still broken,

        var table = new DataTable("Foo");
        table.Columns.AddRange(new []
        {
            new DataColumn("FooPropertyName", typeof(int))
            {
                Unique = true,
                AutoIncrement = true
            },
            new DataColumn("SomeFkPropertyName")
            {
                Unique = true,
                AllowDBNull = true
            },
        });
        table.PrimaryKey = new[] {table.Columns[0]};

        table.Rows.Add(0, 0);
        table.Rows.Add(1, 1);
        table.Rows.Add(2, DBNull.Value);
        table.Rows.Add(3, DBNull.Value); // Exception here

Edit 2

This didn't work either :/

private class MyDbNull
{
    public static MyDbNull Value = new MyDbNull();
    public override bool Equals(object obj)
    {
        return false;
    }

    public override int GetHashCode()
    {
        return 0;
    }
}

table.Rows.Add(2, MyDbNull.Value);
table.Rows.Add(3, MyDbNull.Value);

Upvotes: 1

Related Questions