web-dev-qa-db-ja.com

Entity FrameworkオブジェクトをDatagridview C#にバインド

Entity FrameworkオブジェクトをDataGridViewにバインドしようとしましたが、行き止まりになり続け、どこにも答えが見つからないようです。

テーブル全体(エンティティ)をグリッドビューにバインドできます。これにより、次のように変更を加えて、それらの変更をDBに保存できます。

    WS_Model.WS_Entities context;

    private void simpleButton1_Click(object sender, EventArgs e)
    {
        context = new WS_Entities();

        var query = from c in context.Users select c;

        var users = query.ToList();

        gridControl1.DataSource = users;
    }

    private void simpleButton2_Click(object sender, EventArgs e)
    {
        context.SaveChanges();
    }

しかし、私は私のデータベースのテーブルのすべての列をデータグリッドビューで見たくないので、このようにしてみました...

WS_Entities context = new WS_Entities();

    private void simpleButton1_Click(object sender, EventArgs e)
    {
        var query = from c in context.Users
                    where c.UserName == "James"
                    select new { c.UserName, c.Password, c.Description };

        var results = query.ToList();

        gridControl1.DataSource = results;
    }

    private void simpleButton2_Click(object sender, EventArgs e)
    {
        context.SaveChanges();
    }

しかし、今ではDataGridViewのデータを編集できません。

私はここで木の木材を見ることができません-誰かが私のやり方の誤りを指摘したり、頭脳流出を起こしているときにEFをWinformsにバインドするためのベストプラクティスを教えてください。

私はそれがセクションに関係していることがわかります:

select new { c.UserName, c.Password, c.Description }

しかし、その理由はわかりません。

32
Jimbo James

ラインの問題:

select new { c.UserName, c.Password, c.Description }

匿名型 を作成しており、匿名型は不変である-つまり読み取り専用です。これが、変更が新しいタイプまたは元のEFオブジェクトに反映されない理由です。

さて、バインドしているオブジェクトのすべての列を表示しない方法については、以下の3つのオプションがあります。

不要な列を非表示にする

最も簡単なアプローチは、表示したくない列のvisibleプロパティをfalseに設定することです。

dataGridView1.Columns[0].Visible = false;

Columnsコレクションインデクサーの値は、列の場所を指定する整数または列の名前の文字列のいずれかです。

このデータバインディングのためのEFのカスタムオブジェクト

EFレイヤーでこれを処理することもできます。不要な列なしでEFがデータベースからマップするバインディング用のカスタムオブジェクトを作成します。私はEF 4.0をまったく使用していませんが、今ではこの機能があることを理解しています。

EFオブジェクトから投影され、その後マッピングされたカスタムDTO

3番目のオプション(そして、これらは私の意見では良いから悪いへと進んでいますが、いくつかのアプローチをお話ししたいと思います!)具象型にクエリし、EFオブジェクトにマップし直すことです。何かのようなもの:

private class DataBindingProjection
{
    public string UserName { get; set; };
    public string Password { get; set; };
    public string Description { get; set; };
}

private void simpleButton1_Click(object sender, EventArgs e)
{
    context = new WS_Entities();
    var query = from c in context.Users
                where c.UserName == "James"
                select new DataBindingProjection { UserName = c.UserName, Password = c.Password, Description = c.Description };
    var users = query.ToList();
    gridControl1.DataSource = users;
}

private void simpleButton2_Click(object sender, EventArgs e) 
{
    // and here you have some code to map the properties back from the 
    // projection objects to your datacontext

    context.SaveChanges();
}

特定の状況では、それも実行可能なソリューションになる可能性があります...

38
David Hall