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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.81800 の関連記事表示

<< 0 >>
■81800  データベースからのデータ読込
□投稿者/ 夜叉丸 -(2016/11/15(Tue) 14:41:20)

    分類:[C#] 

    以下のエラーメッセージが表示されます。
    「制約を有効にできませんでした、行に入力できるのは・・・」

    調べてみると EnforceConstraints を使うとありますが
    使い方がわかりません。

    データセットは MAINDataSet と SUBDataSet があり、
    以下のようなデータベースのデータがあり

    MAINDataSet.dbo.Main (キーは NAME です。)
    NAME NUM
    A 1
    B 2

    SUBDataSet.dbo.Sub (キーは SUBNAME です。)
    NAME SUBNAME
    A a1
    A a2
    B b1
    B b2

    Main のデータにSub を JOIN して以下のデータを取得します。
    NAME NUM SUBNAME
    A 1 a1
    A 1 a2
    B 2 b1
    B 2 b2


    キーはNAMEしかないのでエラーが出るのはわかったのですが

    どうすればこのデータをとってくることができますか?
親記事 /過去ログ139より / 関連記事表示
削除チェック/

■81802  Re[1]: データベースからのデータ読込
□投稿者/ 魔界の仮面弁士 -(2016/11/15(Tue) 14:59:16)
    No81800 (夜叉丸 さん) に返信
    > データセットは MAINDataSet と SUBDataSet があり、

    一つの DataSet 内に、Main テーブルと Sub テーブルがあるのではなく、
    Main テーブル用の DataSet (MAINDataSet)と
    Sub テーブル用の DataSet (SUBDataSet) があるということでしょうか。


    どういうコードを書いているのか分かりませんが、
    「JOIN した結果を格納する DataTable」の列定義が
    どのように設定されているのかを、まずは確認してみてください。
記事No.81800 のレス /過去ログ139より / 関連記事表示
削除チェック/

■81803  Re[1]: データベースからのデータ読込
□投稿者/ 魔界の仮面弁士 -(2016/11/15(Tue) 15:14:37)
    No81800 (夜叉丸 さん) に返信
    > Main のデータにSub を JOIN して以下のデータを取得します。

    サーバー側に再問い合わせしたり、LINQ を使ってみるなど、
    やり方はいろいろと考えられますが、現時点で
    Main / Sub のデータを既に DataSet に読み込んでいるならば、
    一つの DataSet 上に DataRelation を貼っておき、
    Sub 側に「親テーブルの NUM 列」を式列として追加するのが
    手っ取り早い気がします。



    // 一つの DataSet 内に二つのDataTable
    var ds = new DataSet();
    var tblM = ds.Tables.Add("dbo.Main");
    var tblS = ds.Tables.Add("dbo.Sub");

    // このあたりはテーブル定義なので、
    // 型付きDataSet を使うのならば意識しなくてOK
    tblM.PrimaryKey = new DataColumn[] { tblM.Columns.Add("NAME") };
    tblM.Columns.Add("NUM", typeof(decimal));

    tblS.Columns.Add("NAME");
    tblS.PrimaryKey = new DataColumn[] { tblS.Columns.Add("SUBNAME") };

    // とりあえず実験用データの登録
    tblM.Rows.Add("A", 1m);
    tblM.Rows.Add("B", 2m);
    tblM.AcceptChanges();
    tblS.Rows.Add("A", "a1");
    tblS.Rows.Add("A", "a2");
    tblS.Rows.Add("B", "b1");
    tblS.Rows.Add("B", "b2");
    tblS.AcceptChanges();

    // ここから本題
    // JOIN 操作のために式列(Expression Column)を利用してみます
    ds.Relations.Add("Main_Sub", tblM.Columns["NAME"], tblS.Columns["NAME"]);
    tblS.Columns.Add("NUM", tblM.Columns["NUM"].DataType, "Parent.NUM");


    これで、tblS 上に、NAME, SUBNAME, NUM の 3 列が構成されます。
    (DataRelation は、型付き DataSet 上であらかじめ構築しておくこともできます)
記事No.81800 のレス /過去ログ139より / 関連記事表示
削除チェック/

■81804  Re[2]: データベースからのデータ読込
□投稿者/ 夜叉丸 -(2016/11/15(Tue) 15:37:12)
    魔界の仮面弁士さんありがとうございます。

    少し難しくて理解できないのですが、

    VisualStudioを使用しています。
    データソースを使用して、サーバーにあるデータベースのデータのDataSetを作りました。

    プロジェクトに以下のファイルが追加されます。
    1.MAINDataSet.xsd 他が追加されます。
    2.SUBDataSet.xsd 他が追加されます。

    MainDataSet.xsd のデザイン編集で
    クエリの追加を行って以下のコードを記入します。

    SELECT A1.NAME, A1.NUM, A2.SUBNAME
    FROM MAINDataSet AS A1
    LEFT OUTER JOIN AS A2
    ON A1.NAME = A2.NAME

    DataTable を返す にて GetMainSubName にして登録


    public class GetMain
    {
    static MAINDataSetAdapters.MainTableAdapter adpt = new MAINDataSetAdapters.MainTableAdapter();

    pubic static MainDataSet.MainDataTable GetMainSubName()
    {
    return(adpt.GetMainSubName());
    }
    }

    この GetMain.GetMainSubName()を呼び出すとエラーになります。

    以下のように Main の NAME を変更すればデータは読み出すことは
    できるとは思いますが、本意ではありません。

    SELECT A1.NAME + ',' + A2.SUBNAME AS NAME, A1.NUM, A2.SUBNAME
    FROM MAINDataSet AS A1
    LEFT OUTER JOIN AS A2
    ON A1.NAME = A2.NAME

    EnforceConstraints を使えばよいらしいですが
    どのようにすればよいのでしょうか?
記事No.81800 のレス /過去ログ139より / 関連記事表示
削除チェック/

■81805  Re[3]: データベースからのデータ読込
□投稿者/ 魔界の仮面弁士 -(2016/11/15(Tue) 16:03:49)
    No81804 (夜叉丸 さん) に返信
    > MainDataSet.xsd のデザイン編集で
    > クエリの追加を行って以下のコードを記入します。

    Main 側に追加しているのだとしたら、まずそこが間違っています。

    Main テーブルは NAME をキーとしており、
    現時点で 2 行のデータが入る事が期待されますよね。


    しかし作成した GetMainSubName のクエリーは、
    SUBNAME をキー(あるいは PrimaryKey なし)とした、
    4 行のデータであるはずです。

    でもそれは Main ではなく、むしろ Sub のテーブルの構造ですよね?


    ですからデザイン時に行う作業としては、以下のいずれかにしてみてください。

    (案1) JOIN 結果の格納先は、Main でも Sub でもなく、
      別の DataTable として TableAdapter を構成する。

    (案2) Sub テーブル側に、GetMainSubName のクエリーを追加する。


    サーバー側に問い合わせを行うのなら、通常は案 1 で良いと思います。
    Main や Sub は 2 列構成ですが、JOIN 結果は 3 列構成なので、
    今回のケースではこれが妥当かと思います。

    もしも案2 を選択するのであれば、Sub の DataTable に、デザイン時に
    SUBNAME な列も追加しておけば OK です。(デザイン時に SUBNAME 列を
    追加していなかったとしても、インデクサ指定で扱うことができます)

    ただし、JOIN 結果のために SUBNAME 列を追加しておいた場合、
    既定の GetData/Fill で取得したデータ(SUBNAME 列の無い SELECT SQL)では、
    SUBNAME 列に入る値が無いため、その列の値は NULL 値として処理されます。


    なお、編集結果をデータベース側に復元する事を考えているのであれば、
    先の回答のように、リレーション構成にしてクライアント側で連結させるか、
    あるいは、案2 を用いて、Sub の DataTable 側で処理すれば OK です。




    > EnforceConstraints を使えばよいらしいですが

    そもそも EnforceConstraints は既定で有効になっています。

    EnforceConstraints が true な状態では、

    ・PrimaryKey な列に、同じデータが重複登録された場合
    ・MaxLength を超える長さのデータが登録された場合
    ・AllowDBNull = false な列が NULL 値の状態であった場合
    ・DataRelation に違反するようなデータ構成になった場合

    などの不整合が検出され、エラー(というか例外)として通知されますが、
    EnforceConstraints を切ってしまうと、そういった違反データを
    DataTable に登録できてしまうことになりますよ。
記事No.81800 のレス /過去ログ139より / 関連記事表示
削除チェック/

■81806  Re[4]: データベースからのデータ読込
□投稿者/ 夜叉丸 -(2016/11/15(Tue) 16:18:29)
    No81805 (魔界の仮面弁士 さん) に返信
    >別の DataTable として TableAdapter を構成する。

    これはあらかじめSQLServerManagementStudioで
    Name と SubName をキーにしたテーブルを作っておくということでしょうか?
    それとも SQLコード内で新たに NAME, SUBName をキーにしたテーブルを
    作成してデータを返すことが可能なのでしょうか?



    ちなみにいろいろ調べて、Get を Fill に変更して以下のようにするとデータを
    取得することができましたが、これはやってはいけないことなのでしょうか?

    pubic static MainDataSet.MainDataTable FillMainSubName()
    {
     MainDataSet Main_DataSet = new Main_DataSet
     Main_DataSet.EnforceConstraints = false;
     adpt.FillMainSubName(Main_DataSet.MAIN);
     return(Main_DataSet.MAIN);
    }
記事No.81800 のレス /過去ログ139より / 関連記事表示
削除チェック/

■81808  Re[5]: データベースからのデータ読込
□投稿者/ 魔界の仮面弁士 -(2016/11/15(Tue) 18:21:33)
    No81806 (夜叉丸 さん) に返信
    > これはあらかじめSQLServerManagementStudioで
    > Name と SubName をキーにしたテーブルを作っておくということでしょうか?

    SQL Server 側に、ビューやテーブルを用意しておく必要はありません。
    C# 側の DataSet のみを編集すれば OK です。

    ドロップ生成された型付き DataSet を編集してみてください。
    デザイナ画面の余白部分(水色縞)を右クリックして、TableAdapter を作成し、
    そこに JOIN クエリーを追加することで生成できます。
    そのテーブルに、PrimaryKey の設定を施すかどうかは任意です。


    > ちなみにいろいろ調べて、Get を Fill に変更して以下のようにするとデータを
    > 取得することができましたが、これはやってはいけないことなのでしょうか?

    一切の制約が無視されますので、あまりお奨めはしません。
    データ加工などのために、一時的に制約をオフにする事はありますが、
    基本的には制約を有効にしたままで運用されるべきものかと。

    逆に、その制約が不要だというのなら、あらかじめデザイン時に
    PrimaryKey 設定や列サイズなどといった不要な制約を、
    最初から *.xsd のデザイン時に外しておけば良いわけで。
記事No.81800 のレス /過去ログ139より / 関連記事表示
削除チェック/

■81820  Re[6]: データベースからのデータ読込
□投稿者/ 夜叉丸 -(2016/11/16(Wed) 13:16:31)
    No81808 (魔界の仮面弁士 さん) に返信

    > デザイナ画面の余白部分(水色縞)を右クリックして、TableAdapter を作成し、
    > そこに JOIN クエリーを追加することで生成できます。
    > そのテーブルに、PrimaryKey の設定を施すかどうかは任意です。

    テーブルの追加できるんですね。はじめて知りました。
    これだと自由にテーブルが作れそうです。
    どうも、ありがとうございました。

記事No.81800 のレス / END /過去ログ139より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -