質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

1957閲覧

配列型の要素を分解して各列に割り当てる

Q10

総合スコア12

DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2021/08/20 14:57

編集2021/08/20 15:07

1,AA,"{1,2,3}"
2,BB,"{4,5,6}"
3,CC,
4,DD,"{10,11,12}"

というCSVファイルを読み込み、{1, 2, 3}のような配列型を分解して、DataGridに

NoNameFavorite_0001Favorite_0002Favorite_0003
1AA123
2BB456
3CC
4DD101112

のように割り当てたいです。
そして、その分解したデータのまま、PostgreSQLに書き込みたいです。

しかし、分解は出来たのですが、Favorite_0001しか定義できておらず、

NoNameFavorite_0001Favorite_0002Favorite_0003
1AA1
2BB4
3CC
4DD10

になってしまっています。

ソース

Cat.cs

C#

1namespace WpfApp1 2{ 3 [Table("tblcat")] 4 class Cat 5 { 6 [Key] 7 [DatabaseGenerated(DatabaseGeneratedOption.None)] 8 [Column("no", Order = 2)] 9 public int No { get; set; } 10 [Key] 11 [DatabaseGenerated(DatabaseGeneratedOption.None)] 12 [Column("name", Order = 1)] 13 public String Name { get; set; } 14 [Column("favorite")] 15 public string? Favorite_0001 { get; set; } 16 //public string? Favorite_0002 { get; set; } 17 //public string? Favorite_0003 { get; set; } 18 } 19}

CatModel.cs

C#

1namespace WpfApp1 2{ 3 public class CatModel 4 { 5 public CatModel(int No, String Name, string? Favorite_0001) 6 //public CatModel(int No, String Name, string? Favorite_0001, string? Favorite_0002, string? Favorite_0003) 7 { 8 this.IsChecked = false; 9 this.No = No; 10 this.Name = Name; 11 this.Favorite_0001 = Favorite_0001; 12 //this.Favorite_0002 = Favorite_0002; 13 //this.Favorite_0003 = Favorite_0003; 14 } 15 public Boolean IsChecked { get; set; } 16 public int No { get; set; } 17 public String Name { get; set; } 18 public string? Favorite_0001 { get; set; } 19 //public string? Favorite_0002 { get; set; } 20 //public string? Favorite_0003 { get; set; } 21 } 22}

MainWindow.xaml

C#

1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 mc:Ignorable="d" 7 Title="List" Height="350" Width="750" 8 BorderThickness="1" 9 > 10 <Grid Height="350" Width="700"> 11 <DataGrid Name="dataGrid" HorizontalAlignment="Left" Margin="10,43,0,0" Width="650" Height="225"> 12 <DataGrid.Columns> 13 <DataGridTemplateColumn IsReadOnly="True" Header="Select" Width="50"> 14 <DataGridTemplateColumn.CellTemplate> 15 <DataTemplate> 16 <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 17 </DataTemplate> 18 </DataGridTemplateColumn.CellTemplate> 19 </DataGridTemplateColumn> 20 <DataGridTextColumn Binding="{Binding No}" ClipboardContentBinding="{x:Null}" Header="No" IsReadOnly="True" Width="50"/> 21 <DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="Name" IsReadOnly="True" Width="100"/> 22 <DataGridTextColumn Binding="{Binding Favorite_0001}" ClipboardContentBinding="{x:Null}" Header="Favorite_0001" IsReadOnly="True" Width="*"/> 23 <DataGridTextColumn Binding="{Binding Favorite_0002}" ClipboardContentBinding="{x:Null}" Header="Favorite_0002" IsReadOnly="True" Width="*"/> 24 <DataGridTextColumn Binding="{Binding Favorite_0003}" ClipboardContentBinding="{x:Null}" Header="Favorite_0003" IsReadOnly="True" Width="*"/> 25 </DataGrid.Columns> 26 </DataGrid> 27 <Button x:Name="imp_button" Content="Import CSV" HorizontalAlignment="Left" Margin="250,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="imp_button_Click"/> 28 </Grid> 29</Window>

MainWindow.xaml.cs

C#

1namespace WpfApp1 2{ 3 public partial class MainWindow : Window 4 { 5 public MainWindow() 6 { 7 InitializeComponent(); 8 using (var conn = new NpgsqlConnection("Server=localhost; Port=5432; Database=DB01;User Id=USER01;Password=USER01;")) 9 { 10 conn.Open(); 11 12 using (var command = conn.CreateCommand()) 13 { 14 StringBuilder sb = new StringBuilder(); 15 16 sb.Clear(); 17 sb.Append("CREATE TABLE IF NOT EXISTS dora.tblcat ("); 18 sb.Append(" no INTEGER NOT NULL"); 19 sb.Append(" , name VARCHAR(20) NOT NULL"); 20 sb.Append(" , favorite VARCHAR(40)"); 21 sb.Append(" , PRIMARY KEY (no, name)"); 22 sb.Append(")"); 23 24 command.CommandText = sb.ToString(); 25 command.ExecuteNonQuery(); 26 } 27 Actual_Search(); 28 conn.Close(); 29 } 30 } 31 32 private void Actual_Search() 33 { 34 BackgroundWorker worker = new BackgroundWorker(); 35 worker.DoWork += SearchProcess; 36 worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SearchProcessCompleted); 37 worker.RunWorkerAsync(); 38 } 39 40 private void searchData() 41 { 42 using (var context = new PgDbContext()) 43 { 44 var tblCat = context.Cats; 45 IQueryable<Cat> result; 46 result = from x in tblCat 47 select x; 48 this.dataGrid.ItemsSource = result.ToList(); 49 } 50 } 51 52 private void SearchProcess(object sender, DoWorkEventArgs e) 53 { 54 using (var context = new PgDbContext()) 55 { 56 var tblCat = context.Cats; 57 IQueryable<Cat> result; 58 result = from x in tblCat 59 select x; 60 61 List<CatModel> resultList = new List<CatModel>(); 62 foreach (Cat cat in result.ToList()) 63 { 64 resultList.Add(new CatModel(cat.No, cat.Name, cat.Favorite_0001)); 65 //resultList.Add(new CatModel(cat.No, cat.Name, cat.Favorite_0001, cat.Favorite_0002, cat.Favorite_0003)); 66 } 67 e.Result = resultList; 68 } 69 } 70 71 private void SearchProcessCompleted(object sender, RunWorkerCompletedEventArgs e) 72 { 73 this.dataGrid.ItemsSource = e.Result as List<CatModel>; 74 } 75 76 private void imp_button_Click(object sender, RoutedEventArgs e) 77 { 78 OpenFileDialog ofd = new OpenFileDialog(); 79 ofd.FileName = ""; 80 ofd.DefaultExt = "*.csv"; 81 if (ofd.ShowDialog() == false) 82 { 83 return; 84 } 85 86 List<Cat> list = readFile(ofd.FileName); 87 88 int count = 0; 89 using (var context = new PgDbContext()) 90 { 91 var table = context.Cats; 92 93 foreach (Cat cat in list) 94 { 95 if (table.SingleOrDefault(x => x.No == cat.No) == null) 96 { 97 context.Cats.Add(cat); 98 context.SaveChanges(); 99 count++; 100 } 101 } 102 } 103 MessageBox.Show(count + " / " + list.Count + " Data Imported"); 104 105 searchData(); 106 Actual_Search(); 107 } 108 109 private static List<Cat> readFile(string filePath) 110 { 111 FileInfo fileInfo = new FileInfo(filePath); 112 List<Cat> list = new List<Cat>(); 113 using (TextFieldParser tfp = new TextFieldParser(fileInfo.FullName, Encoding.GetEncoding("UTF-8"))) 114 { 115 tfp.TextFieldType = FieldType.Delimited; 116 tfp.Delimiters = new string[] { "," }; 117 tfp.HasFieldsEnclosedInQuotes = true; 118 tfp.TrimWhiteSpace = true; 119 while (!tfp.EndOfData) 120 { 121 string[] fields = tfp.ReadFields(); 122 Cat cat = new Cat(); 123 cat.No = int.Parse(fields[0]); 124 cat.Name = fields[1]; 125 var numbers = Regex.Match(fields[2], @"\{(?<numbers>[\d,]+)\}").Groups["numbers"].Value; 126 var collectionOfNumbers = numbers.Split(','); 127 cat.Favorite_0001 = collectionOfNumbers[0]; 128 //cat.Favorite_0002 = collectionOfNumbers[1]; 129 //cat.Favorite_0003 = collectionOfNumbers[2]; 130 list.Add(cat); 131 } 132 } 133 return list; 134 } 135 } 136}

PgDbContext.cs

C#

1namespace WpfApp1 2{ 3 class PgDbContext : DbContext 4 { 5 private const string ConnectionString = "Server=localhost;User ID=USER01;Password=USER01;Database=DB01;port=5432"; 6 7 public PgDbContext() : base(new NpgsqlConnection(ConnectionString), true) { } 8 9 public DbSet<Cat> Cats { get; set; } 10 11 protected override void OnModelCreating(DbModelBuilder modelBuilder) 12 { 13 modelBuilder.HasDefaultSchema("dora"); 14 Database.SetInitializer<PgDbContext>(null); 15 } 16 } 17}

試したこと

コメントアウト行の通り、Favorite_0002とFavorite_0003を追加しましたが、

PostgresException: 42703: column Extent1.Favorite_0002 does not exist

というエラーが出ます。

別にcollectionOfNumbersを直接表示させてもいいのですが、その方法が分かりません。

また、PostgreSQLではunnestという命令を使って配列型を分解できるようですが、
C#上でそれができるのかは分かりません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/08/21 00:23 編集

WPF + DataGrid は必須ですか? WinForms + DataGridView という選択肢はありませんか? (後者ならすぐ紹介できるサンプルがあるので聞いてます) ←思い違いでした。すみません、忘れてください。
退会済みユーザー

退会済みユーザー

2021/08/21 00:45

開発環境を質問欄を編集して追記願います。OS, Visual Studio のバージョン、.NET Framework or Core どっちかとそのバージョンなど。 CREATE TABLE の中に、 > sb.Append(" , favorite VARCHAR(40)"); 上記しかなくて、Favorite_0001, Favorite_0002, Favorite_0003 列を作らないのは何故ですか?
Q10

2021/08/21 11:43

お陰様で解決しました! すみません、一度は書いたのですが、10,000行の制限に引っ掛かったため、消してしまいました。 OS: Windows10 IDE: Visual Studio Community 2019 Version 16.10.3 .NET Framework: 4.8.04084 >CREATE TABLE の中に、 > >> sb.Append(" , favorite VARCHAR(40)"); > >上記しかなくて、Favorite_0001, Favorite_0002, Favorite_0003 列を作らないのは何故ですか? まず、記述に間違いがありましたので訂正させて下さい。 誤:その分解したデータのまま、PostgreSQLに書き込みたいです。                ↓ 正:その分解したデータをまた{1,2,3}のような配列型に戻してPostgreSQLのfavoriteに書き込みたいです。 そして、これがFavorite_0001, Favorite_0002, Favorite_0003 列を作らない理由です。 すみません、こんな前提条件に間違いがあれば正しい回答が出せないですよね。 ・・・実はここから配列型に戻す案を延々と書いて「ここまでは分かるのですが、どこに書けばいいのか分かりません」と書いたところで解決案が浮かびました。それには回答者様お二人のご指摘にヒントを得ました。(今はまだ、データがNullの場合は読み込めてないので、別の質問をするかもしれませんが)本当に助かりました。ありがとうございました!
退会済みユーザー

退会済みユーザー

2021/08/21 11:52

なんかとっても変だと思います。普通に混乱を招かないように作るなら、CSV, DataGrid, DB すべて同じ形式で作るのでは? DataDrid に表示するときだけ形式を変えるというのがどうしても解せませんけど・・・
guest

回答1

0

ベストアンサー

クラス定義には

C#

1[Column("favorite")] 2public string? Favorite_0001 { get; set; } 3public string? Favorite_0002 { get; set; } 4public string? Favorite_0003 { get; set; }

Favorite_0001はfavoriteというカラムだと定義していますが
Favorite_0002、Favorite_0003は定義がありません。

テーブル定義には

C#

1sb.Append("CREATE TABLE IF NOT EXISTS dora.tblcat ("); 2sb.Append(" no INTEGER NOT NULL"); 3sb.Append(" , name VARCHAR(20) NOT NULL"); 4sb.Append(" , favorite VARCHAR(40)"); 5sb.Append(" , PRIMARY KEY (no, name)"); 6sb.Append(")");

上記のようにfavoriteしか定義していませんのでFavorite_0002、Favorite_0003に関しては
そのままのカラム名でデータベースに追加しようとしてエラーになっているのではないですか?

投稿2021/08/20 22:32

YAmaGNZ

総合スコア10251

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Q10

2021/08/21 11:42

お陰様で解決しました! まず、記述に間違いがありましたので訂正させて下さい。 誤:その分解したデータのまま、PostgreSQLに書き込みたいです。                ↓ 正:その分解したデータをまた{1,2,3}のような配列型に戻してPostgreSQLのfavoriteに書き込みたいです。 その説明をしようといろいろ書いているうちに、以下の解決案が浮かびました: List<CatModel> resultList = new List<CatModel>(); foreach (Cat cat in result.ToList()) { var numbers = Regex.Match(cat.Favorite_0001, @"\{(?<numbers>[\d,]+)\}").Groups["numbers"].Value; var collectionOfNumbers = numbers.Split(','); resultList.Add(new CatModel(cat.No, cat.Name, collectionOfNumbers[0], collectionOfNumbers[1], collectionOfNumbers[2])); } 表示だけ1, 2, 3と分解したいので、CatModelを読み込む部分で分解すればよかったんですね。 これで正しく表示されました。 ただ、質問に載せたCSVの3行目にはNullデータがありますが、これは読めなくて、{7,8,9}で埋めたものしか読めていません。Nullableの設定とか見直してみますが、また質問するかもしれません。 今回は回答者様お二人のご指摘にヒントを得ました。本当に助かりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問