2 // Rafael Mizrahi <rafim@mainsoft.com>
3 // Erez Lotan <erezl@mainsoft.com>
4 // Oren Gurfinkel <oreng@mainsoft.com>
7 // Copyright (c) 2004 Mainsoft Co.
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using NUnit.Framework;
32 using MonoTests.System.Data.Utils;
34 namespace MonoTests.System.Data
36 [TestFixture] public class ForeignKeyConstraintTest2
38 [Test] public void Columns()
41 DataSet ds = new DataSet();
42 DataTable dtParent = DataProvider.CreateParentDataTable();
43 DataTable dtChild = DataProvider.CreateChildDataTable();
44 ds.Tables.Add(dtParent);
45 ds.Tables.Add(dtChild);
47 ForeignKeyConstraint fc = null;
48 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
51 Assert.AreEqual(dtChild.Columns[0] , fc.Columns[0] , "FKC1");
54 Assert.AreEqual(1 , fc.Columns.Length , "FKC2");
57 [Test] public void Equals()
59 DataSet ds = new DataSet();
60 DataTable dtParent = DataProvider.CreateParentDataTable();
61 DataTable dtChild = DataProvider.CreateChildDataTable();
62 ds.Tables.Add(dtParent);
63 ds.Tables.Add(dtChild);
64 dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns[0]};
65 ds.EnforceConstraints = true;
67 ForeignKeyConstraint fc1,fc2;
68 fc1 = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
70 fc2 = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[1]);
72 Assert.AreEqual(false, fc1.Equals(fc2), "FKC3");
74 //Two System.Data.ForeignKeyConstraint are equal if they constrain the same columns.
76 fc2 = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
77 Assert.AreEqual(true, fc1.Equals(fc2), "FKC4");
80 [Test] public void RelatedColumns()
82 DataSet ds = new DataSet();
83 DataTable dtParent = DataProvider.CreateParentDataTable();
84 DataTable dtChild = DataProvider.CreateChildDataTable();
85 ds.Tables.Add(dtParent);
86 ds.Tables.Add(dtChild);
87 ForeignKeyConstraint fc = null;
88 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
91 Assert.AreEqual(new DataColumn[] {dtParent.Columns[0]}, fc.RelatedColumns , "FKC5");
94 [Test] public void RelatedTable()
96 DataSet ds = new DataSet();
97 DataTable dtParent = DataProvider.CreateParentDataTable();
98 DataTable dtChild = DataProvider.CreateChildDataTable();
99 ds.Tables.Add(dtParent);
100 ds.Tables.Add(dtChild);
101 ForeignKeyConstraint fc = null;
102 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
105 Assert.AreEqual(dtParent, fc.RelatedTable , "FKC6");
108 [Test] public void Table()
110 DataSet ds = new DataSet();
111 DataTable dtParent = DataProvider.CreateParentDataTable();
112 DataTable dtChild = DataProvider.CreateChildDataTable();
113 ds.Tables.Add(dtParent);
114 ds.Tables.Add(dtChild);
115 ForeignKeyConstraint fc = null;
116 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
119 Assert.AreEqual(dtChild , fc.Table , "FKC7");
122 [Test] public new void ToString()
124 DataTable dtParent = DataProvider.CreateParentDataTable();
125 DataTable dtChild = DataProvider.CreateChildDataTable();
127 ForeignKeyConstraint fc = null;
128 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
130 // ToString - default
131 Assert.AreEqual(string.Empty , fc.ToString(), "FKC8");
133 fc = new ForeignKeyConstraint("myConstraint",dtParent.Columns[0],dtChild.Columns[0]);
134 // Tostring - Constraint name
135 Assert.AreEqual("myConstraint", fc.ToString(), "FKC9");
138 [Test] public void acceptRejectRule()
140 DataSet ds = getNewDataSet();
142 ForeignKeyConstraint fc = new ForeignKeyConstraint(ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]);
143 fc.AcceptRejectRule= AcceptRejectRule.Cascade;
144 ds.Tables[1].Constraints.Add(fc);
148 ds.Tables[0].Rows[0]["ParentId"] = 777;
149 Assert.AreEqual(true, ds.Tables[1].Select("ParentId=777").Length > 0 , "FKC10");
150 ds.Tables[0].RejectChanges();
151 Assert.AreEqual(0, ds.Tables[1].Select("ParentId=777").Length , "FKC11");
153 private DataSet getNewDataSet()
155 DataSet ds1 = new DataSet();
156 ds1.Tables.Add(DataProvider.CreateParentDataTable());
157 ds1.Tables.Add(DataProvider.CreateChildDataTable());
158 // ds1.Tables.Add(DataProvider.CreateChildDataTable());
159 ds1.Tables[0].PrimaryKey= new DataColumn[] {ds1.Tables[0].Columns[0]};
164 [Test] public void constraintName()
166 DataSet ds = new DataSet();
167 DataTable dtParent = DataProvider.CreateParentDataTable();
168 DataTable dtChild = DataProvider.CreateChildDataTable();
169 ds.Tables.Add(dtParent);
170 ds.Tables.Add(dtChild);
172 ForeignKeyConstraint fc = null;
173 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
176 Assert.AreEqual(string.Empty , fc.ConstraintName , "FKC12");
178 fc.ConstraintName = "myConstraint";
181 Assert.AreEqual("myConstraint" , fc.ConstraintName , "FKC13");
184 [Test] public void ctor_ParentColChildCol()
186 DataTable dtParent = DataProvider.CreateParentDataTable();
187 DataTable dtChild = DataProvider.CreateChildDataTable();
188 DataSet ds = new DataSet();
189 ds.Tables.Add(dtChild);
190 ds.Tables.Add(dtParent);
192 ForeignKeyConstraint fc = null;
194 // Ctor ArgumentException
197 fc = new ForeignKeyConstraint(new DataColumn[] {dtParent.Columns[0]} ,new DataColumn[] {dtChild.Columns[0],dtChild.Columns[1]});
198 Assert.Fail("FKS14: ctor Indexer Failed to throw ArgumentException");
200 catch (ArgumentException) {}
201 catch (AssertionException exc) {throw exc;}
202 catch (Exception exc)
204 Assert.Fail("FKS15: ctor. Wrong exception type. Got:" + exc);
207 fc = new ForeignKeyConstraint(new DataColumn[] {dtParent.Columns[0],dtParent.Columns[1]} ,new DataColumn[] {dtChild.Columns[0],dtChild.Columns[2]});
209 // Add constraint to table - ArgumentException
212 dtChild.Constraints.Add(fc);
213 Assert.Fail("FKS16: ctor Indexer Failed to throw ArgumentException");
215 catch (ArgumentException) {}
216 catch (AssertionException exc) {throw exc;}
217 catch (Exception exc)
219 Assert.Fail("FKC17: ctor. Wrong exception type. Got:" + exc);
222 // Child Table Constraints Count - two columnns
223 Assert.AreEqual(0, dtChild.Constraints.Count , "FKC18");
225 // Parent Table Constraints Count - two columnns
226 Assert.AreEqual(1, dtParent.Constraints.Count , "FKC19");
228 // DataSet relations Count
229 Assert.AreEqual(0, ds.Relations.Count , "FKC20");
231 dtParent.Constraints.Clear();
232 dtChild.Constraints.Clear();
234 fc = new ForeignKeyConstraint(new DataColumn[] {dtParent.Columns[0]} ,new DataColumn[] {dtChild.Columns[0]});
236 Assert.AreEqual(false , fc == null , "FKC21");
238 // Child Table Constraints Count
239 Assert.AreEqual(0, dtChild.Constraints.Count , "FKC22");
241 // Parent Table Constraints Count
242 Assert.AreEqual(0, dtParent.Constraints.Count , "FKC");
244 // DataSet relations Count
245 Assert.AreEqual(0, ds.Relations.Count , "FKC23");
247 dtChild.Constraints.Add(fc);
249 // Child Table Constraints Count, Add
250 Assert.AreEqual(1, dtChild.Constraints.Count , "FKC24");
252 // Parent Table Constraints Count, Add
253 Assert.AreEqual(1, dtParent.Constraints.Count , "FKC25");
255 // DataSet relations Count, Add
256 Assert.AreEqual(0, ds.Relations.Count , "FKC26");
258 // Parent Table Constraints type
259 Assert.AreEqual(typeof(UniqueConstraint), dtParent.Constraints[0].GetType() , "FKC27");
261 // Parent Table Constraints type
262 Assert.AreEqual(typeof(ForeignKeyConstraint), dtChild.Constraints[0].GetType() , "FKC28");
264 // Parent Table Primary key
265 Assert.AreEqual(0, dtParent.PrimaryKey.Length , "FKC29");
267 dtChild.Constraints.Clear();
268 dtParent.Constraints.Clear();
269 ds.Relations.Add(new DataRelation("myRelation",dtParent.Columns[0],dtChild.Columns[0]));
271 // Relation - Child Table Constraints Count
272 Assert.AreEqual(1, dtChild.Constraints.Count , "FKC30");
274 // Relation - Parent Table Constraints Count
275 Assert.AreEqual(1, dtParent.Constraints.Count , "FKC31");
277 // Relation - Parent Table Constraints type
278 Assert.AreEqual(typeof(UniqueConstraint), dtParent.Constraints[0].GetType() , "FKC32");
280 // Relation - Parent Table Constraints type
281 Assert.AreEqual(typeof(ForeignKeyConstraint), dtChild.Constraints[0].GetType() , "FKC33");
283 // Relation - Parent Table Primary key
284 Assert.AreEqual(0, dtParent.PrimaryKey.Length , "FKC34");
287 [Test] public void ctor_NameParentColChildCol()
289 DataTable dtParent = DataProvider.CreateParentDataTable();
290 DataTable dtChild = DataProvider.CreateChildDataTable();
292 ForeignKeyConstraint fc = null;
293 fc = new ForeignKeyConstraint("myForeignKey",dtParent.Columns[0],dtChild.Columns[0]);
296 Assert.AreEqual(false , fc == null , "FKC35");
299 Assert.AreEqual("myForeignKey" , fc.ConstraintName , "FKC36");
302 [Test] public void ctor_NameParentColsChildCols()
304 DataTable dtParent = DataProvider.CreateParentDataTable();
305 DataTable dtChild = DataProvider.CreateChildDataTable();
307 ForeignKeyConstraint fc = null;
308 fc = new ForeignKeyConstraint("myForeignKey",new DataColumn[] {dtParent.Columns[0]} ,new DataColumn[] {dtChild.Columns[0]});
311 Assert.AreEqual(false , fc == null , "FKC37");
314 Assert.AreEqual("myForeignKey" , fc.ConstraintName , "FKC38");
317 [Test] public void deleteRule()
319 DataSet ds = new DataSet();
320 DataTable dtParent = DataProvider.CreateParentDataTable();
321 DataTable dtChild = DataProvider.CreateChildDataTable();
322 ds.Tables.Add(dtParent);
323 ds.Tables.Add(dtChild);
324 dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns[0]};
325 ds.EnforceConstraints = true;
327 ForeignKeyConstraint fc = null;
328 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
332 Assert.AreEqual(Rule.Cascade , fc.DeleteRule , "FKC39");
335 foreach (Rule rule in Enum.GetValues(typeof(Rule)))
338 fc.DeleteRule = rule;
339 Assert.AreEqual(rule, fc.DeleteRule , "FKC40");
342 dtChild.Constraints.Add(fc);
344 //checking delete rule
346 // Rule = None, Delete Exception
347 fc.DeleteRule = Rule.None;
348 //Exception = "Cannot delete this row because constraints are enforced on relation Constraint1, and deleting this row will strand child rows."
351 dtParent.Rows.Find(1).Delete();
352 Assert.Fail("FKC41: Find Indexer Failed to throw InvalidConstraintException");
354 catch (InvalidConstraintException) {}
355 catch (AssertionException exc) {throw exc;}
356 catch (Exception exc)
358 Assert.Fail("FKC42: Find. Wrong exception type. Got:" + exc);
361 // Rule = None, Delete succeed
362 fc.DeleteRule = Rule.None;
363 foreach (DataRow dr in dtChild.Select("ParentId = 1"))
365 dtParent.Rows.Find(1).Delete();
366 Assert.AreEqual(0, dtParent.Select("ParentId=1").Length , "FKC43");
369 fc.DeleteRule = Rule.Cascade;
370 dtParent.Rows.Find(2).Delete();
371 Assert.AreEqual(0, dtChild.Select("ParentId=2").Length , "FKC44");
374 DataSet ds1 = new DataSet();
375 ds1.Tables.Add(DataProvider.CreateParentDataTable());
376 ds1.Tables.Add(DataProvider.CreateChildDataTable());
378 ForeignKeyConstraint fc1 = new ForeignKeyConstraint(ds1.Tables[0].Columns[0],ds1.Tables[1].Columns[1]);
379 fc1.DeleteRule = Rule.SetNull;
380 ds1.Tables[1].Constraints.Add(fc1);
382 Assert.AreEqual(0, ds1.Tables[1].Select("ChildId is null").Length, "FKC45");
384 ds1.Tables[0].PrimaryKey= new DataColumn[] {ds1.Tables[0].Columns[0]};
385 ds1.Tables[0].Rows.Find(3).Delete();
387 ds1.Tables[0].AcceptChanges();
388 ds1.Tables[1].AcceptChanges();
390 DataRow[] arr = ds1.Tables[1].Select("ChildId is null");
392 /*foreach (DataRow dr in arr)
394 Assert.AreEqual(null, dr["ChildId"], "FKC");
397 Assert.AreEqual(4, arr.Length , "FKC46");
400 //fc.DeleteRule = Rule.SetDefault;
402 ds1.Tables.Add(DataProvider.CreateParentDataTable());
403 ds1.Tables.Add(DataProvider.CreateChildDataTable());
405 fc1 = new ForeignKeyConstraint(ds1.Tables[0].Columns[0],ds1.Tables[1].Columns[1]);
406 fc1.DeleteRule = Rule.SetDefault;
407 ds1.Tables[1].Constraints.Add(fc1);
408 ds1.Tables[1].Columns[1].DefaultValue="777";
410 //Add new row --> in order to apply the forigen key rules
411 DataRow dr2 = ds1.Tables[0].NewRow();
412 dr2["ParentId"] = 777;
413 ds1.Tables[0].Rows.Add(dr2);
415 ds1.Tables[0].PrimaryKey= new DataColumn[] {ds1.Tables[0].Columns[0]};
416 ds1.Tables[0].Rows.Find(3).Delete();
417 Assert.AreEqual(4, ds1.Tables[1].Select("ChildId=777").Length , "FKC47");
420 [Test] public void extendedProperties()
422 DataTable dtParent = DataProvider.CreateParentDataTable();
423 DataTable dtChild = DataProvider.CreateParentDataTable();
425 ForeignKeyConstraint fc = null;
426 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
428 PropertyCollection pc = fc.ExtendedProperties ;
430 // Checking ExtendedProperties default
431 Assert.AreEqual(true, fc != null, "FKC48");
433 // Checking ExtendedProperties count
434 Assert.AreEqual(0, pc.Count , "FKC49");
438 public void ctor_DclmDclm()
440 DataTable dtParent = DataProvider.CreateParentDataTable();
441 DataTable dtChild = DataProvider.CreateChildDataTable();
442 DataSet ds = new DataSet();
443 ds.Tables.Add(dtChild);
444 ds.Tables.Add(dtParent);
446 ForeignKeyConstraint fc = null;
447 fc = new ForeignKeyConstraint(dtParent.Columns[0],dtChild.Columns[0]);
449 Assert.IsFalse(fc == null ,"FKC64" );
451 Assert.AreEqual(0,dtChild.Constraints.Count ,"FKC50");
453 Assert.AreEqual(0,dtParent.Constraints.Count ,"FKC51");
455 Assert.AreEqual(0,ds.Relations.Count ,"FKC52");
457 dtChild.Constraints.Add(fc);
459 Assert.AreEqual(1,dtChild.Constraints.Count ,"FKC53");
461 Assert.AreEqual(1,dtParent.Constraints.Count ,"FKC54");
463 Assert.AreEqual(0,ds.Relations.Count ,"FKC55");
465 Assert.AreEqual(typeof(UniqueConstraint),dtParent.Constraints[0].GetType() ,"FKC56");
467 Assert.AreEqual(typeof(ForeignKeyConstraint),dtChild.Constraints[0].GetType() ,"FKC57");
469 Assert.AreEqual(0,dtParent.PrimaryKey.Length ,"FKC58");
471 dtChild.Constraints.Clear();
472 dtParent.Constraints.Clear();
473 ds.Relations.Add(new DataRelation("myRelation",dtParent.Columns[0],dtChild.Columns[0]));
475 Assert.AreEqual(1,dtChild.Constraints.Count ,"FKC59");
477 Assert.AreEqual(1,dtParent.Constraints.Count ,"FKC60");
479 Assert.AreEqual(typeof(UniqueConstraint),dtParent.Constraints[0].GetType() ,"FKC61");
481 Assert.AreEqual(typeof(ForeignKeyConstraint),dtChild.Constraints[0].GetType() ,"FKC62");
483 Assert.AreEqual(0,dtParent.PrimaryKey.Length ,"FKC63");
487 [ExpectedException(typeof(NullReferenceException))]
488 public void ctor_DclmDclm1()
490 ForeignKeyConstraint fc = new ForeignKeyConstraint((DataColumn)null,(DataColumn)null);
494 [ExpectedException(typeof(ArgumentException))]
495 public void ctor_DclmDclm2()
497 DataSet ds = new DataSet();
498 ds.Tables.Add(DataProvider.CreateParentDataTable());
499 ds.Tables.Add(DataProvider.CreateChildDataTable());
500 ds.Tables["Parent"].Columns["ParentId"].Expression = "2";
502 ForeignKeyConstraint fc = new ForeignKeyConstraint(ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]);
506 [ExpectedException(typeof(ArgumentException))]
507 public void ctor_DclmDclm3()
509 DataSet ds = new DataSet();
510 ds.Tables.Add(DataProvider.CreateParentDataTable());
511 ds.Tables.Add(DataProvider.CreateChildDataTable());
512 ds.Tables["Child"].Columns["ParentId"].Expression = "2";
514 ForeignKeyConstraint fc = new ForeignKeyConstraint(ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]);
518 public void UpdateRule1()
520 DataSet ds = GetNewDataSet();
521 ForeignKeyConstraint fc = new ForeignKeyConstraint(ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]);
522 fc.UpdateRule=Rule.Cascade;
523 ds.Tables[1].Constraints.Add(fc);
525 //Changing parent row
527 ds.Tables[0].Rows.Find(1)["ParentId"] = 8;
529 ds.Tables[0].AcceptChanges();
530 ds.Tables[1].AcceptChanges();
533 Assert.IsTrue(ds.Tables[1].Select("ParentId=8").Length > 0, "FKC66");
538 [ExpectedException(typeof(ConstraintException))]
539 public void UpdateRule2()
541 DataSet ds = GetNewDataSet();
542 ds.Tables[0].PrimaryKey=null;
543 ForeignKeyConstraint fc = new ForeignKeyConstraint(ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]);
544 fc.UpdateRule=Rule.None;
545 ds.Tables[1].Constraints.Add(fc);
547 //Changing parent row
549 ds.Tables[0].Rows[0]["ParentId"] = 5;
551 /*ds.Tables[0].AcceptChanges();
552 ds.Tables[1].AcceptChanges();
554 Compare(ds.Tables[1].Select("ParentId=8").Length ,0);*/
558 public void UpdateRule3()
560 DataSet ds = GetNewDataSet();
561 ForeignKeyConstraint fc = new ForeignKeyConstraint(ds.Tables[0].Columns[0],ds.Tables[1].Columns[1]);
562 fc.UpdateRule=Rule.SetDefault;
563 ds.Tables[1].Constraints.Add(fc);
565 //Changing parent row
567 ds.Tables[1].Columns[1].DefaultValue="777";
569 //Add new row --> in order to apply the forigen key rules
570 DataRow dr = ds.Tables[0].NewRow();
571 dr["ParentId"] = 777;
572 ds.Tables[0].Rows.Add(dr);
575 ds.Tables[0].Rows.Find(1)["ParentId"] = 8;
577 ds.Tables[0].AcceptChanges();
578 ds.Tables[1].AcceptChanges();
581 Assert.IsTrue(ds.Tables[1].Select("ChildId=777").Length > 0, "FKC67");
585 public void UpdateRule4()
587 DataSet ds = GetNewDataSet();
588 ForeignKeyConstraint fc = new ForeignKeyConstraint(ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]);
589 fc.UpdateRule=Rule.SetNull;
590 ds.Tables[1].Constraints.Add(fc);
592 //Changing parent row
594 ds.Tables[0].Rows.Find(1)["ParentId"] = 8;
596 ds.Tables[0].AcceptChanges();
597 ds.Tables[1].AcceptChanges();
600 Assert.IsTrue(ds.Tables[1].Select("ParentId is null").Length > 0, "FKC68");
604 private DataSet GetNewDataSet()
606 DataSet ds1 = new DataSet();
607 ds1.Tables.Add(DataProvider.CreateParentDataTable());
608 ds1.Tables.Add(DataProvider.CreateChildDataTable());
609 ds1.Tables[0].PrimaryKey= new DataColumn[] {ds1.Tables[0].Columns[0]};
614 public void ForeignConstraint_DateTimeModeTest()
616 DataTable t1 = new DataTable("t1");
617 t1.Columns.Add("col", typeof(DateTime));
619 DataTable t2 = new DataTable("t2");
620 t2.Columns.Add("col", typeof(DateTime));
621 t2.Columns[0].DateTimeMode = DataSetDateTime.Unspecified;
623 // DataColumn type shud match, and no exception shud be raised
624 t2.Constraints.Add("fk", t1.Columns[0], t2.Columns[0]);
626 t2.Constraints.Clear();
627 t2.Columns[0].DateTimeMode = DataSetDateTime.Local;
629 // DataColumn type shud not match, and exception shud be raised
630 t2.Constraints.Add("fk", t1.Columns[0], t2.Columns[0]);
632 } catch (InvalidOperationException e) {}
636 public void ParentChildSameColumn ()
638 DataTable dataTable = new DataTable ("Menu");
639 DataColumn colID = dataTable.Columns.Add ("ID", typeof (int));
640 DataColumn colCulture = dataTable.Columns.Add ("Culture", typeof (string));
641 dataTable.Columns.Add ("Name", typeof (string));
642 DataColumn colParentID = dataTable.Columns.Add ("ParentID", typeof (int));
644 // table PK (ID, Culture)
645 dataTable.Constraints.Add (new UniqueConstraint (
647 new DataColumn [] { colID, colCulture },
650 // add a FK referencing the same table: (ID, Culture) <- (ParentID, Culture)
651 ForeignKeyConstraint fkc = new ForeignKeyConstraint (
653 new DataColumn [] { colID, colCulture },
654 new DataColumn [] { colParentID, colCulture });
656 dataTable.Constraints.Add (fkc);