Home All Groups Group Topic Archive Search About

Modifiying a dataview while enumeration it (1.x->2.0 broke)

Author
6 Nov 2005 6:05 AM
Greg Burns
I have a DataView that is currently sorted by the Price column.  The sort is
critical to the logic I am applying.

In .NET 1.x, it seems I was able to modify the Price column in my DataView
while enumerating it without any side effect.  I know this is a bad idea,
but it was working. :)

It appears in .NET 2.0 this no longer works the same way.  I had recompiled
my program in 2.0 and now my output changed. I've narrowed it down to this
bit of code. :(

Anyways, I need some help with rethinking how to do this.

dv.Sort = "Price DESC"
'dv.RowStateFilter = DataViewRowState.Unchange ' thinking this maybe the
key, modified rows will fall out of the enumeration perhaps

for each drv as datarowview in dv
  ' some logic
  drv("Price") = something new value
next

I've considered cloning the underlying datatable and making a new dataview
so that the enumration won't be effected as I change the Price column.  (I
do believe that is what is happening now, which I don't think happened
before).  But if I am enumerating a copy of the dataview, then how to I
update my Price column back in the original table (all I have a reference to
is drv from the copy)?  I hate to have to resort to some sort of Find
command, but it that is what it takes...

All suggestions welcome,
Greg

Author
6 Nov 2005 9:18 AM
Miha Markic [MVP C#]
Hi Greg,

You can easily create another DataView on the same table and do updates
there.

--
Miha Markic [MVP C#]
RightHand .NET consulting & development www.rthand.com
Blog: http://cs.rthand.com/blogs/blog_with_righthand/


Show quote
"Greg Burns" <bluebunny@newsgroups.nospam> wrote in message
news:url4dgp4FHA.636@TK2MSFTNGP10.phx.gbl...
>I have a DataView that is currently sorted by the Price column.  The sort
>is critical to the logic I am applying.
>
> In .NET 1.x, it seems I was able to modify the Price column in my DataView
> while enumerating it without any side effect.  I know this is a bad idea,
> but it was working. :)
>
> It appears in .NET 2.0 this no longer works the same way.  I had
> recompiled my program in 2.0 and now my output changed. I've narrowed it
> down to this bit of code. :(
>
> Anyways, I need some help with rethinking how to do this.
>
> dv.Sort = "Price DESC"
> 'dv.RowStateFilter = DataViewRowState.Unchange ' thinking this maybe the
> key, modified rows will fall out of the enumeration perhaps
>
> for each drv as datarowview in dv
>  ' some logic
>  drv("Price") = something new value
> next
>
> I've considered cloning the underlying datatable and making a new dataview
> so that the enumration won't be effected as I change the Price column.  (I
> do believe that is what is happening now, which I don't think happened
> before).  But if I am enumerating a copy of the dataview, then how to I
> update my Price column back in the original table (all I have a reference
> to is drv from the copy)?  I hate to have to resort to some sort of Find
> command, but it that is what it takes...
>
> All suggestions welcome,
> Greg
>
>
>
Author
6 Nov 2005 12:55 PM
Greg Burns
That seems like wise advice, but I not sure how to apply it.

Say I have two DataViews; dv1 & dv2. Both are the same filtered records from
original DataTable. Now I start enumerating over dv1. How do I change the
same row in dv2 without using some sort of Find command on dv2 based on
current datarowview in dv1?

Now that I think about it, not sure this will work either.  As I modify the
Price column in dv2 won't it dynamically change the sort of dv1?  Almost
seems like in .NET 1.x, that a dataview's sort order was static and now in
..NET 2.0 it can change as the underlying data changes.  (I would have
thought it was always this way, but something's definately different since
my output changed after recompiling.)

I am beginning to think I need to have two Price columns.  One I sort on
(who's value never changes), and one I update.  Not very elegant.

Greg

Show quote
"Miha Markic [MVP C#]" <miha at rthand com> wrote in message
news:eo65UMr4FHA.1276@TK2MSFTNGP09.phx.gbl...
> Hi Greg,
>
> You can easily create another DataView on the same table and do updates
> there.
>
> --
> Miha Markic [MVP C#]
> RightHand .NET consulting & development www.rthand.com
> Blog: http://cs.rthand.com/blogs/blog_with_righthand/
Author
6 Nov 2005 1:22 PM
Greg Burns
I threw together a small demo to see what the heck is going on:

        Dim dt As New DataTable
        dt.Columns.Add("price", GetType(System.Int32))

        Dim dr As DataRow

        dr = dt.NewRow
        dr("price") = "1"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = "2"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = "3"
        dt.Rows.Add(dr)

        Dim dv As DataView = dt.DefaultView
        dv.Sort = "price ASC"

        For Each drv As DataRowView In dv
            If drv("price") = 1 Then
                drv("price") = 4
            End If
            Console.WriteLine("{0}", drv("price"))
        Next

        Console.ReadLine()

In .NET 1.1 the output is:

4
2
1

In .NET 2.0 the output changes to:

2
3
4

<sigh>


Show quote
"Greg Burns" <bluebunny@newsgroups.nospam> wrote in message
news:u8dhjFt4FHA.1476@TK2MSFTNGP10.phx.gbl...
> That seems like wise advice, but I not sure how to apply it.
>
> Say I have two DataViews; dv1 & dv2. Both are the same filtered records
> from original DataTable. Now I start enumerating over dv1. How do I change
> the same row in dv2 without using some sort of Find command on dv2 based
> on current datarowview in dv1?
>
> Now that I think about it, not sure this will work either.  As I modify
> the Price column in dv2 won't it dynamically change the sort of dv1?
> Almost seems like in .NET 1.x, that a dataview's sort order was static and
> now in .NET 2.0 it can change as the underlying data changes.  (I would
> have thought it was always this way, but something's definately different
> since my output changed after recompiling.)
>
> I am beginning to think I need to have two Price columns.  One I sort on
> (who's value never changes), and one I update.  Not very elegant.
>
> Greg
>
> "Miha Markic [MVP C#]" <miha at rthand com> wrote in message
> news:eo65UMr4FHA.1276@TK2MSFTNGP09.phx.gbl...
>> Hi Greg,
>>
>> You can easily create another DataView on the same table and do updates
>> there.
>>
>> --
>> Miha Markic [MVP C#]
>> RightHand .NET consulting & development www.rthand.com
>> Blog: http://cs.rthand.com/blogs/blog_with_righthand/
>
>
Author
6 Nov 2005 1:46 PM
Greg Burns
Whoops! That should have said:

In .NET 1.1 the output is:

4
2
3

In .NET 2.0 the output changes to:

2
3
4

sorry for the confusion

Show quote
"Greg Burns" <bluebunny@newsgroups.nospam> wrote in message
news:OyIo3Ut4FHA.1464@tk2msftngp13.phx.gbl...
>I threw together a small demo to see what the heck is going on:
>
>        Dim dt As New DataTable
>        dt.Columns.Add("price", GetType(System.Int32))
>
>        Dim dr As DataRow
>
>        dr = dt.NewRow
>        dr("price") = "1"
>        dt.Rows.Add(dr)
>
>        dr = dt.NewRow
>        dr("price") = "2"
>        dt.Rows.Add(dr)
>
>        dr = dt.NewRow
>        dr("price") = "3"
>        dt.Rows.Add(dr)
>
>        Dim dv As DataView = dt.DefaultView
>        dv.Sort = "price ASC"
>
>        For Each drv As DataRowView In dv
>            If drv("price") = 1 Then
>                drv("price") = 4
>            End If
>            Console.WriteLine("{0}", drv("price"))
>        Next
>
>        Console.ReadLine()
>
> In .NET 1.1 the output is:
>
> 4
> 2
> 1
>
> In .NET 2.0 the output changes to:
>
> 2
> 3
> 4
>
> <sigh>
>
>
> "Greg Burns" <bluebunny@newsgroups.nospam> wrote in message
> news:u8dhjFt4FHA.1476@TK2MSFTNGP10.phx.gbl...
>> That seems like wise advice, but I not sure how to apply it.
>>
>> Say I have two DataViews; dv1 & dv2. Both are the same filtered records
>> from original DataTable. Now I start enumerating over dv1. How do I
>> change the same row in dv2 without using some sort of Find command on dv2
>> based on current datarowview in dv1?
>>
>> Now that I think about it, not sure this will work either.  As I modify
>> the Price column in dv2 won't it dynamically change the sort of dv1?
>> Almost seems like in .NET 1.x, that a dataview's sort order was static
>> and now in .NET 2.0 it can change as the underlying data changes.  (I
>> would have thought it was always this way, but something's definately
>> different since my output changed after recompiling.)
>>
>> I am beginning to think I need to have two Price columns.  One I sort on
>> (who's value never changes), and one I update.  Not very elegant.
>>
>> Greg
>>
>> "Miha Markic [MVP C#]" <miha at rthand com> wrote in message
>> news:eo65UMr4FHA.1276@TK2MSFTNGP09.phx.gbl...
>>> Hi Greg,
>>>
>>> You can easily create another DataView on the same table and do updates
>>> there.
>>>
>>> --
>>> Miha Markic [MVP C#]
>>> RightHand .NET consulting & development www.rthand.com
>>> Blog: http://cs.rthand.com/blogs/blog_with_righthand/
>>
>>
>
>
Author
7 Nov 2005 9:26 AM
Steven Cheng[MSFT]
Hi Greg,

Thanks for your code snippet. Two things I'd like to confirm:

1. Since you define the column as Int32 type, we should use

drv("price") = 3  rather than  drv("price") = "3"

2. For the .NET 2.0 DataView, when we specify a Sort expression for it and
then modify the DataView's certain DataRowView record's Sorted field, the
DataView collection will automatically resort the DataRowView collection so
as to make it still conform to the Sort expression.   So even we use Index
(rather than foreach ) to access the DataRowView, it will automatically
resort it after any item (the sorted property) in it be changed. The
following test code could demonstrate on this:

=====================
Protected Sub WhileTest()
        Dim dt As New DataTable
        dt.Columns.Add("price", GetType(System.Int32))

        Dim dr As DataRow

        dr = dt.NewRow
        dr("price") = 1
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = 3
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = 5
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = 7
        dt.Rows.Add(dr)

        Dim dv As DataView = New DataView(dt)
        dv.Sort = "price ASC"

        Dim i As Integer = 0

        While i < dv.Count

            If dv(i)("price") = 1 Then
                dv(i)("price") = 8
            End If

            Response.Write(String.Format("<br/>{0}", dv(i)("price")))
            i = i + 1
        End While

    End Sub


Protected Sub DirectModifyTest()
        Dim dt As New DataTable
        dt.Columns.Add("price", GetType(System.Int32))

        Dim dr As DataRow

        dr = dt.NewRow
        dr("price") = 1
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = 3
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = 5
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("price") = 7
        dt.Rows.Add(dr)

        Dim dv As DataView = New DataView(dt)
        dv.Sort = "price ASC"


        dv(2)("price") = 8

        For Each drv As DataRowView In dv
            Response.Write(String.Format("<br/>{0}", drv("price")))
        Next

    End Sub
End Class
===================================

So I think this is a new feature of the .NET 2.0.Also, if you are wanting a
static Row collection which won't be ReSort automatically, I'd suggest you
consider using the
DataTable.Select(filter as String, sort as String) 

which will return a static DataRow[] array.

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)


--------------------
| Reply-To: "Greg Burns" <greg_burns@DONT_SPAM_ME_hotmail.com>
| From: "Greg Burns" <bluebunny@newsgroups.nospam>
| References: <url4dgp4FHA.***@TK2MSFTNGP10.phx.gbl>
<eo65UMr4FHA.1***@TK2MSFTNGP09.phx.gbl>
<u8dhjFt4FHA.1***@TK2MSFTNGP10.phx.gbl>
<OyIo3Ut4FHA.1***@tk2msftngp13.phx.gbl>
Show quote
| Subject: Re: Modifiying a dataview while enumeration it (1.x->2.0 broke)
| Date: Sun, 6 Nov 2005 08:46:50 -0500
| Lines: 102
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2900.2180
| X-RFC2646: Format=Flowed; Response
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
| Message-ID: <eieuLit4FHA.3***@TK2MSFTNGP12.phx.gbl>
| Newsgroups: microsoft.public.dotnet.framework.adonet
| NNTP-Posting-Host: pcp09349975pcs.harngt01.de.comcast.net 68.34.122.119
| Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP12.phx.gbl
| Xref: TK2MSFTNGXA01.phx.gbl microsoft.public.dotnet.framework.adonet:38742
| X-Tomcat-NG: microsoft.public.dotnet.framework.adonet
|
| Whoops! That should have said:
|
| In .NET 1.1 the output is:
|
| 4
| 2
| 3
|
| In .NET 2.0 the output changes to:
|
| 2
| 3
| 4
|
| sorry for the confusion
|
| "Greg Burns" <bluebunny@newsgroups.nospam> wrote in message
| news:OyIo3Ut4FHA.1464@tk2msftngp13.phx.gbl...
| >I threw together a small demo to see what the heck is going on:
| >
| >        Dim dt As New DataTable
| >        dt.Columns.Add("price", GetType(System.Int32))
| >
| >        Dim dr As DataRow
| >
| >        dr = dt.NewRow
| >        dr("price") = "1"
| >        dt.Rows.Add(dr)
| >
| >        dr = dt.NewRow
| >        dr("price") = "2"
| >        dt.Rows.Add(dr)
| >
| >        dr = dt.NewRow
| >        dr("price") = "3"
| >        dt.Rows.Add(dr)
| >
| >        Dim dv As DataView = dt.DefaultView
| >        dv.Sort = "price ASC"
| >
| >        For Each drv As DataRowView In dv
| >            If drv("price") = 1 Then
| >                drv("price") = 4
| >            End If
| >            Console.WriteLine("{0}", drv("price"))
| >        Next
| >
| >        Console.ReadLine()
| >
| > In .NET 1.1 the output is:
| >
| > 4
| > 2
| > 1
| >
| > In .NET 2.0 the output changes to:
| >
| > 2
| > 3
| > 4
| >
| > <sigh>
| >
| >
| > "Greg Burns" <bluebunny@newsgroups.nospam> wrote in message
| > news:u8dhjFt4FHA.1476@TK2MSFTNGP10.phx.gbl...
| >> That seems like wise advice, but I not sure how to apply it.
| >>
| >> Say I have two DataViews; dv1 & dv2. Both are the same filtered
records
| >> from original DataTable. Now I start enumerating over dv1. How do I
| >> change the same row in dv2 without using some sort of Find command on
dv2
| >> based on current datarowview in dv1?
| >>
| >> Now that I think about it, not sure this will work either.  As I
modify
| >> the Price column in dv2 won't it dynamically change the sort of dv1?
| >> Almost seems like in .NET 1.x, that a dataview's sort order was static
| >> and now in .NET 2.0 it can change as the underlying data changes.  (I
| >> would have thought it was always this way, but something's definately
| >> different since my output changed after recompiling.)
| >>
| >> I am beginning to think I need to have two Price columns.  One I sort
on
| >> (who's value never changes), and one I update.  Not very elegant.
| >>
| >> Greg
| >>
| >> "Miha Markic [MVP C#]" <miha at rthand com> wrote in message
| >> news:eo65UMr4FHA.1276@TK2MSFTNGP09.phx.gbl...
| >>> Hi Greg,
| >>>
| >>> You can easily create another DataView on the same table and do
updates
| >>> there.
| >>>
| >>> --
| >>> Miha Markic [MVP C#]
| >>> RightHand .NET consulting & development www.rthand.com
| >>> Blog: http://cs.rthand.com/blogs/blog_with_righthand/
| >>
| >>
| >
| >
|
|
|
Author
7 Nov 2005 12:14 PM
Greg Burns
Thansk for taking a look.

Unfortunately my real project is getting its DataView from a CreateChildRow
statement. So I am kinda stuck with what I got.

I'll tackle this problem in another way.  I just wanted to bring this change
to light in case somebody else runs into it themselves.

Greg


Show quote
"Steven Cheng[MSFT]" <stch***@online.microsoft.com> wrote in message
> So I think this is a new feature of the .NET 2.0.Also, if you are wanting
> a
> static Row collection which won't be ReSort automatically, I'd suggest you
> consider using the
> DataTable.Select(filter as String, sort as String)
>
> which will return a static DataRow[] array.
Author
7 Nov 2005 2:52 PM
QuenHo
Greg,

I got the same problem in 1.x. Sometimes it works, sometimes it
doesn't. I don't thing its 1.x related, but maybe the cleaned the code
up. It's also terribly slow on largers dataviews. I used by mistake not
by design. Yes you have to change your program logic, but in the long
run, I think it's better.

QuenHo

Greg Burns wrote:
Show quote
> Thansk for taking a look.
>
> Unfortunately my real project is getting its DataView from a CreateChildRow
> statement. So I am kinda stuck with what I got.
>
> I'll tackle this problem in another way.  I just wanted to bring this change
> to light in case somebody else runs into it themselves.
>
> Greg
>
>
> "Steven Cheng[MSFT]" <stch***@online.microsoft.com> wrote in message
> > So I think this is a new feature of the .NET 2.0.Also, if you are wanting
> > a
> > static Row collection which won't be ReSort automatically, I'd suggest you
> > consider using the
> > DataTable.Select(filter as String, sort as String)
> >
> > which will return a static DataRow[] array.

AddThis Social Bookmark Button