Unexplained VersionNotFoundException

G

Guest

I've run into a problem that has me pretty confused. I'm getting a
VersionNotFoundException when trying to change the RowFilter property of a
DataView. This happened in a large system that I'm working on, but I've been
able to duplicate the behavior in a relatively small (80 lines) program,
which I've included below (assuming it doesn't get munged by the upload
software).

There is some discussion of similar problems in previous posts here, but I
didn't see a small reproducible case or any kind of resolution to the problem.

Short explanation of program:
I have a DataSet with two tables: Legislators and Authors. The Legislators
table contains a list of all Legislators who can potentially be an author or
coauthor on a bill. The Authors table contains a record for each Legislator
who has signed onto the bill as an author or coauthor (the Authors table will
contain information for one bill at a time). The DataSet enforces a
relation: the LegislatorCode value in an Authors record must match a
LegislatorCode that's in the Legislators table. I use a DataView to maintain
a view of the Legislators table showing only those legislators who have not
signed onto the bill.

This all works on the initial load, as shown in the program below. However,
if I then add an Authors record, the DataView isn't updated to reflect the
change. That is, even though there now is an Authors record for a
legislator, that legislator still shows up in the DataView. So, figuring I
had to trigger a refresh of the DataView, I set RowFilter to string.Empty,
and then set it back to what it was. I then get an exception
"System.Data.VersionNotFoundException: There is no Original data to access."

I have two questions:
1) Why doesn't the DataView update when I enter the new Authors record?
2) Why do I get this exception?

Any help, especially a workaround or somebody pointing out where I'm doing
something wrong, would be appreciated. Program follows.

Jim

--------------

..using System;
..using System.Data;
..namespace dvTest
..{
.. class Class1
.. {
.. [STAThread]
.. static void Main(string[] args)
.. {
.. DataSet myds = new DataSet();
.. // Create the tables
.. DataTable tblLegislators = new DataTable("Legislators");
.. tblLegislators.Columns.Add("LegislatorCode");
.. tblLegislators.Columns.Add("DisplayName");
.. DataTable tblAuthors = new DataTable("Authors");
.. tblAuthors.Columns.Add("BillNumber");
.. tblAuthors.Columns.Add("LegislatorCode");
.. // AuthorType: P = Primary author, C = Coauthor
.. tblAuthors.Columns.Add("AuthorType");
.. // Add tables to dataset
.. myds.Tables.Add(tblLegislators);
.. myds.Tables.Add(tblAuthors);
.. // Add a relationship.
.. myds.Relations.Add(tblLegislators.Columns["LegislatorCode"],
.. tblAuthors.Columns["LegislatorCode"]);
.. // populate the legislators table
.. tblLegislators.Rows.Add(new object[] {"A0123", "Smith (A0123)"});
.. tblLegislators.Rows.Add(new object[] {"A1234", "Jones (A1234)"});
.. tblLegislators.Rows.Add(new object[] {"A5038", "Jackson
(A5038)"});
.. tblLegislators.Rows.Add(new object[] {"A0191", "Morton
(A0191)"});
.. // Populate the Authors table.
.. // LegislatorCode must be present in Legislators table
.. tblAuthors.Rows.Add(new object[] {"001", "A0123", "P"});
.. tblAuthors.Rows.Add(new object[] {"001", "A5038", "C"});
.. // Accept changes on the dataset.
.. myds.AcceptChanges();
.. // dvLegislators is a dataview that contains legislators
.. // that do not have a record in tblAuthors.
.. DataView dvLegislators = new DataView(
.. tblLegislators,
.. "Count(Child.LegislatorCode)=0",
.. "DisplayName",
.. DataViewRowState.CurrentRows);
.. // Show contents
.. ShowLegislators(dvLegislators);
.. // Add another coauthor
.. Console.WriteLine("Add Legislator 0191 as a coauthor");
.. tblAuthors.Rows.Add(new object[] {"001", "A0191", "C"});
.. // Show contents -- why is 0191 still in this DataView?
.. ShowLegislators(dvLegislators);
.. // Re-filter the DataView
.. dvLegislators.RowFilter = "";
.. try
.. {
.. // Why does this throw an exception?
.. dvLegislators.RowFilter = "Count(Child.LegislatorCode)=0";
.. }
.. catch (Exception ex)
.. {
.. Console.WriteLine(ex);
.. }
..
.. Console.WriteLine("Press Enter");
.. Console.ReadLine();
.. }
.. static void ShowLegislators(DataView dvLegislators)
.. {
.. // Display contents of dvLegislators
.. Console.WriteLine("dvLegislators contains:");
.. foreach (DataRowView drv in dvLegislators)
.. {
.. Console.WriteLine(drv["DisplayName"].ToString());
.. }
.. Console.WriteLine();
.. }
.. }
..}
 
G

Guest

A little more experimentation reveals that if I don't accept changes on the
Legislators table after initially populating, then I don't get the exception
when I change the RowFilter property. That is, rather than
"myds.AcceptChanges()", if I code "tblAuthors.AcceptChanges()", I avoid the
exception. It appears that the code that processes the RowFilter change
expects the child side of the relation to have Original values if the parent
side has Original values. Or something like that. It seems kind of goofy to
me.

That behavior does lead me to a possible (although ugly) workaround. I can
arrange to create a Legislators table that doesn't have Original values.
Since the only database updates I make are to the table that's represented by
the Authors DataTable, it doesn't matter what I do to the Legislators
DataTable. It'll make for some pretty strange code, though. I'd be
interested in a better workaround.

Jim
 
M

Miha Markic [MVP C#]

Hi Jim,

Quick question: do you have any DataColumn.Expression set?

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

Jim Mischel said:
I've run into a problem that has me pretty confused. I'm getting a
VersionNotFoundException when trying to change the RowFilter property of a
DataView. This happened in a large system that I'm working on, but I've
been
able to duplicate the behavior in a relatively small (80 lines) program,
which I've included below (assuming it doesn't get munged by the upload
software).

There is some discussion of similar problems in previous posts here, but I
didn't see a small reproducible case or any kind of resolution to the
problem.

Short explanation of program:
I have a DataSet with two tables: Legislators and Authors. The
Legislators
table contains a list of all Legislators who can potentially be an author
or
coauthor on a bill. The Authors table contains a record for each
Legislator
who has signed onto the bill as an author or coauthor (the Authors table
will
contain information for one bill at a time). The DataSet enforces a
relation: the LegislatorCode value in an Authors record must match a
LegislatorCode that's in the Legislators table. I use a DataView to
maintain
a view of the Legislators table showing only those legislators who have
not
signed onto the bill.

This all works on the initial load, as shown in the program below.
However,
if I then add an Authors record, the DataView isn't updated to reflect the
change. That is, even though there now is an Authors record for a
legislator, that legislator still shows up in the DataView. So, figuring
I
had to trigger a refresh of the DataView, I set RowFilter to string.Empty,
and then set it back to what it was. I then get an exception
"System.Data.VersionNotFoundException: There is no Original data to
access."

I have two questions:
1) Why doesn't the DataView update when I enter the new Authors record?
2) Why do I get this exception?

Any help, especially a workaround or somebody pointing out where I'm doing
something wrong, would be appreciated. Program follows.

Jim

--------------

.using System;
.using System.Data;
.namespace dvTest
.{
. class Class1
. {
. [STAThread]
. static void Main(string[] args)
. {
. DataSet myds = new DataSet();
. // Create the tables
. DataTable tblLegislators = new DataTable("Legislators");
. tblLegislators.Columns.Add("LegislatorCode");
. tblLegislators.Columns.Add("DisplayName");
. DataTable tblAuthors = new DataTable("Authors");
. tblAuthors.Columns.Add("BillNumber");
. tblAuthors.Columns.Add("LegislatorCode");
. // AuthorType: P = Primary author, C = Coauthor
. tblAuthors.Columns.Add("AuthorType");
. // Add tables to dataset
. myds.Tables.Add(tblLegislators);
. myds.Tables.Add(tblAuthors);
. // Add a relationship.
. myds.Relations.Add(tblLegislators.Columns["LegislatorCode"],
. tblAuthors.Columns["LegislatorCode"]);
. // populate the legislators table
. tblLegislators.Rows.Add(new object[] {"A0123", "Smith
(A0123)"});
. tblLegislators.Rows.Add(new object[] {"A1234", "Jones
(A1234)"});
. tblLegislators.Rows.Add(new object[] {"A5038", "Jackson
(A5038)"});
. tblLegislators.Rows.Add(new object[] {"A0191", "Morton
(A0191)"});
. // Populate the Authors table.
. // LegislatorCode must be present in Legislators table
. tblAuthors.Rows.Add(new object[] {"001", "A0123", "P"});
. tblAuthors.Rows.Add(new object[] {"001", "A5038", "C"});
. // Accept changes on the dataset.
. myds.AcceptChanges();
. // dvLegislators is a dataview that contains legislators
. // that do not have a record in tblAuthors.
. DataView dvLegislators = new DataView(
. tblLegislators,
. "Count(Child.LegislatorCode)=0",
. "DisplayName",
. DataViewRowState.CurrentRows);
. // Show contents
. ShowLegislators(dvLegislators);
. // Add another coauthor
. Console.WriteLine("Add Legislator 0191 as a coauthor");
. tblAuthors.Rows.Add(new object[] {"001", "A0191", "C"});
. // Show contents -- why is 0191 still in this DataView?
. ShowLegislators(dvLegislators);
. // Re-filter the DataView
. dvLegislators.RowFilter = "";
. try
. {
. // Why does this throw an exception?
. dvLegislators.RowFilter =
"Count(Child.LegislatorCode)=0";
. }
. catch (Exception ex)
. {
. Console.WriteLine(ex);
. }
.
. Console.WriteLine("Press Enter");
. Console.ReadLine();
. }
. static void ShowLegislators(DataView dvLegislators)
. {
. // Display contents of dvLegislators
. Console.WriteLine("dvLegislators contains:");
. foreach (DataRowView drv in dvLegislators)
. {
. Console.WriteLine(drv["DisplayName"].ToString());
. }
. Console.WriteLine();
. }
. }
.}
 
Top