Reputation: 1321
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
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