nrdo-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [nrdo-list] Differences between Update() and UpdateThis()


From: Stuart Ballard
Subject: Re: [nrdo-list] Differences between Update() and UpdateThis()
Date: Thu, 4 May 2006 10:23:05 -0400

Good question :)

In almost all circumstances Update() is the right thing to use. If you
look at the code (off the top of my head I forget whether it's in
Generic nrdo library or in the generated C# file) you'll see that
Update() always ends up eventually calling UpdateThis() which actually
does the work of updating the individual object. Update() sometimes
does some additional work too, though, and in the situations where it
does, it's usually bad to bypass that.

Effectively, UpdateThis() is an implementation detail that (I think)
had to end up in the public API just so that other nrdo-generated code
could call it. I'll check again tonight because it *might* be possible
to just make it private.

That may be enough to answer your question but just in case I'll
explain what the extra work Update() does actually is. To explain that
I'll need to give a little background. This will be long; if you don't
care, skip it :) The scenario I describe isn't the only situation
you'd want to use this, just one that's (comparatively) simple to
explain.

Suppose you have two tables with a one-to-one relationship - say, a
Person table with biographical information and a Student table which
supplements the Person table with information specific to people who
are students. The primary key of the Student table would probably be
the person_id. So something like this:

table person {
 fields {
   int id int notnull readonly [the id of the person];
   string name nvarchar(100) notnull readwrite [the name];
   ...
 };
 pkey sequenced id;
};
table student {
 fields {
   int person_id int notnull readonly [the id of the person this
student information is associated with];
   string major nvarchar(20) notnull readwrite [the student's major];
   ...
 };
 pkey {person_id};
 references single person {fkey cascade; by {person_id id}};
};

Another unrelated bit of background: the usual way to structure an
ASP.NET page that creates or modifies a nrdo object is something like
this:

protected Person person;

public void Page_Load(...) {
 person = Person.GetById(Nint.Parse(Request.QueryString["personId"]));
 if (person == null) person = new Person();
 if (!IsPostBack) {
   // set form field values from person object
 }
}
public void Save_Click(...) {
 if (!Page.IsValid) return;
 // set person object properties from form field values
 person.Update();
}

This structure allows for 99% of the code to be the same between the
scenarios of creating a new person (no personId parameter in the
querystring) and updating an existing one (personId parameter
present).

Now with all that in mind I can describe the situation that would be
problematic if not for the extra work Update() does.

Suppose that instead of a page that's used for creating/editing a
Person, we want a page that's used for creating/editing a Student. And
we want it to create/edit the associated Person record at the same
time; ie, this page is for editing *all* the information about a
student, including the stuff that's in the Person table (this may seem
a bit artificial, but that's only because I struggled to find a pair
of tables with the right relationship between them that I didn't have
to make this even longer to explain. In our application it does come
up a lot).

So now the Page_Load method would start like this:

protected Student student;

public void Page_Load(...) {
 student = Student.GetByPersonId(Nint.Parse(Request.QueryString["personId"]));
 if (student == null) student = new Student(???);
 ...
}

Note the ???. Because the personId field of Student is readonly (and
has to be, because it's the primary key) you need a value for it to
pass to the Student constructor. But there isn't a Person record for
this student in the database yet, because we haven't created it. And
we don't *want* to pre-emptively create one and get it's ID, because
we don't want to create the record until the user presses Save.

So instead nrdo detects the situation where you have a readonly field
that's a foreign key to a "sequenced" pkey on another table, and
creates a second version of the constructor that takes an instance of
the other table as a parameter, instead of an id. So in this case
you'd be able to do:

student = new Student(new Person());

Even though the Person record you are creating hasn't been saved to
the database yet and doesn't have an ID, nrdo still maintains the
relationship between the two objects in memory.

And when you call Update(), the first thing it does is call Update()
on the associated Person object, capture the id, set its own PersonId
to the resulting value, and *then* call UpdateThis().

Whew. More than you ever wanted to know, I'm sure :)

Stuart.

--
http://sab39.dev.netreach.com/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]