C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: LINQ使用のDataGridViewのデータが消える


(過去ログ 46 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■24452 / inTopicNo.1)  LINQ使用のDataGridViewのデータが消える
  
□投稿者/ たこやき (12回)-(2008/09/03(Wed) 11:58:47)

分類:[C#] 

またご迷惑をおかけしますがよろしくお願いします。

C#2008使用
フォームにDataSetをドラッグ&ドロップしてDataGridViewを作成しています。
button1を作成して、以下のようにDataGridViewのデータを絞り込みました。

private void button1_Click(object sender, EventArgs e)
{
var aa =
from p in myDataSet.TBL
where p.FLD.Length < 3
select p;
myBindingSource.DataSource = aa.AsDataView();
}

この後、TBLテーブルのFLD列の文字数を3文字に変更して、
保存かレコード移動を実施すると、データが消えてしまいます。
上のLINQの条件にひっかかって、該当外扱いになる模様です。
その証拠に、全データを表示すると、変更されたデータが現れます。
どうすればこの現象を回避できるのでしょうか?
どなたがご指導お願いします。

引用返信 編集キー/
■24453 / inTopicNo.2)  Re[1]: LINQ使用のDataGridViewのデータが消える
□投稿者/ ネタ好き未記入 (77回)-(2008/09/03(Wed) 12:06:04)
No24452 (たこやき さん) に返信
根本的なところで疑問が生じます。
何故3文字になる事が予め分かっているのに、表示しない条件を設定するのですか?
それを説明しないと誰もわからないと思います。
引用返信 編集キー/
■24454 / inTopicNo.3)  Re[2]: LINQ使用のDataGridViewのデータが消える
□投稿者/ みきぬ (57回)-(2008/09/03(Wed) 12:24:11)
もしかしてこういうことがやりたいのかな?
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=45283&forum=7
引用返信 編集キー/
■24455 / inTopicNo.4)  Re[2]: LINQ使用のDataGridViewのデータが消える
□投稿者/ たこやき (13回)-(2008/09/03(Wed) 12:24:40)
ご返信ありがとうございます。
これは現象を再現する為の例です。
実際の運用は、ある特定文字でデータを絞り込み、
それをもってデータを追加すると、
検索文字が含まれていなかったら消えてしまいます。
また、追加時でなくても、タイトル変更等で検索条件からはずれると
消えてしまうのです。それがこまるのです。
引用返信 編集キー/
■24456 / inTopicNo.5)  Re[3]: LINQ使用のDataGridViewのデータが消える
□投稿者/ たこやき (14回)-(2008/09/03(Wed) 12:34:47)
> http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=45283&forum=7

そうですね。よく似た現象だと思います。
ただ、この例の解決策は、LINQの場合、現実的には厳しいかな?
一旦抽出に成功したものにフラグをつけて、同時に相反するものを抽出して
フラグをはずす。そしてフラグのあるものを再び抽出する。
まーできんでもないかな???
もうちょっといい方法はないでしょうか……
引用返信 編集キー/
■24502 / inTopicNo.6)  Re[4]: LINQ使用のDataGridViewのデータが消える
□投稿者/ たこやき (15回)-(2008/09/03(Wed) 17:10:07)
結局 仕様としてFilter機能が働くのでしょうかね。
プロパティの設定等が見つからなかったので、以下のようにしました。
もっといい方法があったら教えて下さい。

private void button1_Click(object sender, EventArgs e)
{
      // 全データを走査して、フラグを付ける
var aa =
from p in myDataSet.TBL
select p;

foreach (var a in aa)
{
if (a.FLD.Length < 4) a.旗 = true;
else a.旗 = false;
}
      
      // フラグの付いているもののみ抽出
var bb =
from p in myDataSet.TBL
where p.旗 == true
select p;

myBindingSource.DataSource = bb.AsDataView();

      // 以降はフラグ付きを選択するようにセットする
myBindingSource.Filter = "旗=true";
}


解決済み
引用返信 編集キー/
■24504 / inTopicNo.7)  Re[5]: LINQ使用のDataGridViewのデータが消える
□投稿者/ みきぬ (61回)-(2008/09/03(Wed) 17:19:37)
フィルタ条件を「もともとの絞り込み条件 or フラグ」にしておいて、
レコードが編集されたときにフラグを立てておく処理を入れればええんでない?
解決済み
引用返信 編集キー/
■24522 / inTopicNo.8)  Re[6]: LINQ使用のDataGridViewのデータが消える
□投稿者/ たこやき (16回)-(2008/09/03(Wed) 18:39:33)
みきぬさん ありがとうございます。
全くその通りですね。

  // フラグの付いているもののみ抽出
  var bb =
  from p in myDataSet.TBL
  where p.旗 == true
  select p;

  myBindingSource.DataSource = bb.AsDataView();

上記の部分が不要で、すっきりしました。
ありがとうございました。


解決済み
引用返信 編集キー/
■24977 / inTopicNo.9)  Re[7]: LINQ使用のDataGridViewのデータが消える
□投稿者/ たこやき (20回)-(2008/09/12(Fri) 19:08:18)
※※※ 注意!! ※※※

Filterを使用した場合、RichTextBox のバインドがこわれるのでご注意下さい。
データも壊れます。
参考までに、それを検証するソースを掲載します。 
未熟なソースなので、まちがいだらけかもしれませんが……

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data;

namespace BindingSourceExamples
{
public class テスト : Form
{
// *********************************************
// ************* 問題部分 ********************

void 失敗ケース(int x)
{
IEnumerable<DataRow> aa =
from p in dt.AsEnumerable()
select p;

foreach (DataRow a in aa)
a["旗"] = (a.Field<Int32>("ID") > x) ? true : false;

bs.Filter = "旗=true";  // <-- エラー RichTextのバインドが壊れる
}


void 成功ケース(int x)
{
var aa =
from p in dt.AsEnumerable()
where p.Field<Int32>("ID") > x
select p;

bs.DataSource = aa.AsDataView();
}


void ちょっと成功例(int x)
{
IEnumerable<DataRow> aa =
from p in dt.AsEnumerable()
select p;

foreach (DataRow a in aa)
a["旗"] = (a.Field<Int32>("ID") > x) ? true : false;

IEnumerable<DataRow> bb =
from p in dt.AsEnumerable()
where p.Field<bool>("旗") == true
select p;

// CopyToDataTableを使用するとデータ保存できない?
bs.DataSource = bb.CopyToDataTable<DataRow>();
}

// **********************************************
// **********************************************


[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new テスト());
}

RichTextBox rtb = new RichTextBox();
TextBox tb = new TextBox();
Label m1 = new Label();
Label m2 = new Label();
Label m3 = new Label();
Label m4 = new Label();
Button b1 = new Button();
Button b2 = new Button();
Button b3 = new Button();
Button b4 = new Button();
DataGridView dgv = new DataGridView();
BindingSource bs = new BindingSource();
DataTable dt = new DataTable();

public テスト()
{
this.Size = new Size(350, 400);

// コントロール作成
dgv.Location = new Point(10, 10);
dgv.Size = new Size(180,330);
this.Controls.Add(dgv);

m1.Location = new Point(200, 20);
m1.Size = new Size(120,20);
m1.Text = "TextBoxにバインド";
this.Controls.Add(m1);

tb.Location = new Point(200, 40);
tb.Size = new Size(120, 30);
tb.Name = "AAA";
this.Controls.Add(tb);

m2.Location = new Point(200, 70);
m2.Size = new Size(120,20);
m2.Text = "RichBoxにバインド";
this.Controls.Add(m2);

rtb.Location = new Point(200, 90);
rtb.Size = new Size(120, 30);
this.Controls.Add(rtb);

m3.Location = new Point(200, 130);
m3.Size = new Size(120,20);
m3.Text = "@Aは成功ケース";
this.Controls.Add(m3);

b1.Location = new Point(200, 150);
b1.Size = new Size(120, 30);
b1.Text = "@ 8以上選択";
b1.Click += new EventHandler(b1_Click);
this.Controls.Add(b1);

b2.Location = new Point(200, 180);
b2.Size = new Size(120, 30);
b2.Text = "A 2以上選択";
b2.Click += new EventHandler(b2_Click);
this.Controls.Add(b2);

m4.Location = new Point(200, 220);
m4.Size = new Size(120,20);
m4.Text = "BCは失敗ケース";
this.Controls.Add(m4);

b3.Location = new Point(200, 240);
b3.Size = new Size(120, 30);
b3.Text = "@ 8以上選択";
b3.Click += new EventHandler(b3_Click);
this.Controls.Add(b3);

b4.Location = new Point(200, 270);
b4.Size = new Size(120, 30);
b4.Text = "A 2以上選択";
b4.Click += new EventHandler(b4_Click);
this.Controls.Add(b4);



// 列作成
DataColumn c1 = new DataColumn();
c1.DataType = System.Type.GetType("System.Int32");
c1.AllowDBNull = false;
c1.Caption = "ID";
c1.ColumnName = "ID";
dt.Columns.Add(c1);

DataColumn c2 = new DataColumn();
c2.DataType = System.Type.GetType("System.String");
c2.AllowDBNull = false;
c2.Caption = "TEXT";
c2.ColumnName = "TEXT";
dt.Columns.Add(c2);

DataColumn c3 = new DataColumn();
c3.DataType = System.Type.GetType("System.Object");
c3.AllowDBNull = false;
c3.Caption = "RTF";
c3.ColumnName = "RTF";
dt.Columns.Add(c3);

DataColumn c4 = new DataColumn();
c4.DataType = System.Type.GetType("System.Boolean");
c4.AllowDBNull = false;
c4.Caption = "旗";
c4.ColumnName = "旗";
dt.Columns.Add(c4);

// レコード作成
RichTextBox rt = new RichTextBox();
DataRow r;
for (int i = 0; i < 10; i++)
{
r = dt.NewRow();
r["ID"] = i ;
r["TEXT"] = rt.Text = i.ToString();
rt.Text = i.ToString() + i.ToString();
r["RTF"] = rt.Rtf; // 見分けの為重ね文字に
r["旗"] = false;
dt.Rows.Add(r);
}

// バインディングソース作成
bs.DataSource = dt;

// バインディング
dgv.DataSource = bs;
tb.DataBindings.Add(new Binding("Text", bs, "TEXT", true));
rtb.DataBindings.Add(new Binding("Rtf", bs, "RTF", true));

// 列幅設定
dgv.Columns["ID"].Width = 30;
dgv.Columns["TEXT"].Width = 30;
dgv.Columns["RTF"].Width = 30;
dgv.Columns["旗"].Width = 30;
}

void b1_Click(object sender, EventArgs e)
{
成功ケース(6);
}

void b2_Click(object sender, EventArgs e)
{
成功ケース(1);
}

void b3_Click(object sender, EventArgs e)
{
失敗ケース(6);
}

void b4_Click(object sender, EventArgs e)
{
失敗ケース(1);
}
}
}
解決済み
引用返信 編集キー/
■25002 / inTopicNo.10)  Re[8]: LINQ使用のDataGridViewのデータが消える
□投稿者/ たこやき (21回)-(2008/09/13(Sat) 18:09:26)
××× 重大訂正 ×××

ド素人でまちがった情報ばかり発信しています。
もし、参考にされている人がいたら申し訳ありません。訂正してください。

データを壊す原因は、LINQ式の後、foreachで
データを書き換えていることだと思います。
LINQ式はいくつ重ねてもいいみたいですが、データの書換えはやめましょう


// foreachでデータを書き換えるのはやめましょう。
// データがこわれてしまします。
void エラーの原因()
{
var aa =
from p in myDataSet.TBL
select p;

// エラーの原因 データが壊れます。
foreach (var a in aa)
a.旗 = (a.FLD.Length < 4) ? true : false;

myBindingSource.Filter = "旗=true";
}

// 複雑な抽出でもLINQ式内に記述する
void 正しい方法()
{
var aa =
from p in myDataSet.TBL
where p.FLD.Length < 4
select p;

myBindingSource.DataSource = bb.AsDataView();
}

たいへんご迷惑おかけしました。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -