Reputation: 26602
I have a collection of objects with no key or order or other obvious index.
I wish to store data regarding each object in a DataTable. I thought an elegant way of doing this would be to store a reference in the owner column, and make that columns type typeof(MyClass)
.
However, when I try to do this in practice, it doesn't work (it says the primary keys collide). Turns out that putting the instances into a row field just writes "MyProgram.MyClass
" into the field - presumably the output of toString
even though that row's type was supposed to be MyClass
not string
.
Here is some sample code which works in LINQPad:
void Main()
{
// Create a table
var table = new DataTable();
var ownerColumn = new DataColumn("Owner", typeof(MyClass));
var primaryKey = new[] { ownerColumn };
table.Columns.AddRange(primaryKey);
table.PrimaryKey = primaryKey;
table.Columns.Add(new DataColumn("Some Data", typeof(int)) { DefaultValue = 0 });
// Create 2 objects
var c1 = new MyClass();
var c2 = new MyClass();
// Store their data in the table
var row = table.NewRow();
row["Owner"] = c1;
row["Some Data"] = 1;
table.Rows.Add(row);
row = table.NewRow();
row["Owner"] = c2;
row["Some Data"] = 2;
table.Rows.Add(row);
}
// Define other methods and classes here
class MyClass {
}
What do I do to solve this? Do I have to make an id
field in MyClass
, then use id
to fill in the owner column, and then make sure each object receives a unique id
at creation myself?
Upvotes: 2
Views: 4535
Reputation: 21485
You have to implement System.IComparable
(non-generic version) interface on MyClass
so that DataTable
knows how to to compare the value of the column. If this interface is not defined, the code falls back on comparing object.ToString() results.
Upvotes: 2
Reputation: 63065
You can use auto increment column :
DataTable dTable = new DataTable();
DataColumn auto = new DataColumn("AutoID", typeof(System.Int32));
dTable.Columns.Add(auto);
auto.AutoIncrement = true;
auto.AutoIncrementSeed = 1;
auto.ReadOnly = true;
Upvotes: 1