0

I have this piece of code that I need to repeat a lot of times (dt_Areas and dt_Locations are DataTable objects):

ForeignKeyConstraint fkC = 
  new ForeignKeyConstraint(dt_Areas.Columns["Id"],
                           dt_Locations.Columns["AreaId"]);
fkC.DeleteRule = Rule.None;
fkC.UpdateRule = Rule.None;

In all cases, my DeleteRule and UpdateRule must be the same.

So I thought, let's look for a constructor, containing rule definitions too, which led me to this piece of code:

dt_Locations.Constraints.Add(
  new ForeignKeyConstraint("Location_Areas", 
                           "Areas",
                           "",
                           new string[]{ "AreaId" },
                           new string[] {"Id" }, 
                           AcceptRejectRule.None,
                           Rule.None,
                           Rule.None));

This does not work, due to a NullReferenceException referring to the Constraints property, so let's solve that issue:

dt_Locations.Constraints = new ConstraintCollection();
...

But this seems not to be allowed, as you can see from this build result:

error CS0200: Property or indexer 'DataTable.Constraints' cannot be assigned to --
it is read only

First of all, I don't understand where this is coming from: pressing F12 leads me to this piece of code:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[ResCategoryAttribute("DataCategory_Data")]
[ResDescriptionAttribute("DataTableConstraintsDescr")]
public ConstraintCollection Constraints { get; }

The property is public and the switches in the preceding lines don't show "read-only" (at least not that I understand).

So my question is: as I have quite a lot of tables to cover, how can I add a constraint at runtime, preferably using a one-liner?

Dominique
  • 16,450
  • 15
  • 56
  • 112
  • Create your own specialized class with its own constructor that defaults the rules as you want? – SMor Aug 26 '21 at 12:18
  • @SMor: is this a serious answer? I have no idea what you mean, I just want to use the .Net standard classes for DB handling. – Dominique Aug 26 '21 at 12:20
  • I don't know anything about SQL server, but can't you just do `new ForeignKeyConstraint(dt_Areas.Columns["Id"], dt_Locations.Columns["AreaId"]) { DeleteRule = Rule.None, UpdateRule = Rule.None }`? – Sweeper Aug 26 '21 at 12:20
  • @Sweeper: that's the solution indeed. I have no idea why it works, but this is what I am looking for. Please write it down as an answer, I'll accept it. – Dominique Aug 26 '21 at 12:23

1 Answers1

0

To turn that code into a single statement, you just need an object initialiser:

var fkC = 
  new ForeignKeyConstraint(dt_Areas.Columns["Id"],dt_Locations.Columns["AreaId"])
    { 
        DeleteRule = Rule.None, 
        UpdateRule = Rule.None 
    };

... and this piece of code makes it possible to add that constraint to the DataTable.Constraints property:

dt_Locations.Constraints.Add(
  new ForeignKeyConstraint(dt_Areas.Columns["Id"], 
                           dt_Locations.Columns["AreaId"])
    { DeleteRule = Rule.None, 
      UpdateRule = Rule.None });

(This is split over multiple lines for readability reasons, but it can be written as a one-liner very easy.)

Dominique
  • 16,450
  • 15
  • 56
  • 112
Sweeper
  • 213,210
  • 22
  • 193
  • 313