1

メモリ内のlinqエンティティ結果セットにデータバインドされたリストボックス内のアイテムの再ソートを許可しようとしています。エンティティ レコードは次のように構成されています。

public class DisplayEntity
{
    public int IDPK { get; set; }
    public int OrderInt { get; set; }
    public string Name { get; set; }
}

これらは、フォーム ロード メソッドとファクタ メソッドで整数列によってロードおよびソートされます。

IQueryable<DisplayEntity> entitylist = null;
private void WindowForm_Load(object sender, EventArgs e)
{
    entitylist = from e in dbcontext select e;
    RefreshList();
}
private void RefreshList()
{
    entitylist = entitylist.OrderBy(e => e.OrderInt); //order by
    dbcontext.Refresh(RefreshMode.KeepChanges, entitylist);
    listBoxEntities.DataSource = entitylist;
}

データセットが初めて読み込まれると正しく並べ替えられますが、その後のデータ変更と RefreshList() 呼び出しではエンティティ リストが並べ替えられません。

private void ChangeOrder(int argIDPK, int argNewPosition)
{
    DisplayEntity tempe = (from e in entitylist where e.IDPK == argIDPK select e).First();
    tempe.OrderInt = argNewPosition;
    RefreshList();
}

ChangeOrder メソッドを使用するのと同様に、メモリ内のエンティティ リスト エンティティの 1 つの名前を変更すると、RefreshList( ) 電話。

4

1 に答える 1

2

これはクエリであることを覚えておく必要entityListがあります。これはメモリ内のエンティティの単純なリストではなく、「並べ替え」またはエンティティを検索するたびにデータベースに対して実行されます。同時に、Linq to Sql はデータベースから返されたオブジェクトを追跡します。同じ ID を持つエンティティがメモリ内に存在する場合は、新しいクエリの結果に再利用されます。

したがって、次のようになります。

private void WindowForm_Load(object sender, EventArgs e)
{
    entitylist = dbcontext.Entities; // SELECT * FROM Entities
    RefreshList();
}

private void ChangeOrder(int argIDPK, int argNewPosition)
{
    // SELECT TOP(1) * FROM Entities WHERE IDPK = @argIDPK
    // query is executed here
    DisplayEntity tempe = entitylist.First(e => e.IDPK == argIDPK);
    tempe.OrderInt = argNewPosition;
    RefreshList();
}

private void RefreshList()
{
    // SELECT * FROM Entities ORDER BY OrderInt
    entitylist = entitylist.OrderBy(e => e.OrderInt);
    dbcontext.Refresh(RefreshMode.KeepChanges, entitylist);
    // query is executed here
    listBoxEntities.DataSource = entitylist;
}

ここで、データベースからの OrderInt フィールド値 (つまり、元の並べ替え) によって並べ替えられたエンティティがデータベースから返されるという注意が必要な瞬間です。ただし、これらのクエリ結果がメモリ オブジェクトにマップされると、値が変更されたインスタンスが使用されます。したがって、データベース値の順序でソートされた、ローカルで変更された値を持つエンティティがあります。

それを修正する方法 - ローカルで変更するときにデータベースの値を更新するだけです:

private void ChangeOrder(int argIDPK, int argNewPosition)
{
    DisplayEntity tempe = entitylist.First(e => e.IDPK == argIDPK);
    tempe.OrderInt = argNewPosition;
    dbcontext.SubmitChanges(); // here we update database
    RefreshList();
}

IQueryableまたは、ここの代わりにメモリ内リストを使用します。

List<DisplayEntity> entitylist = null;

private void WindowForm_Load(object sender, EventArgs e)
{
    // query is executed only here
    entitylist = dbcontext.Entities.OrderBy(e => e.OrderInt).ToList();
    RefreshList();
}

private void RefreshList()
{    
    listBoxEntities.DataSource = entitylist.OrderBy(e => e.OrderInt).ToList();
}

private void ChangeOrder(int argIDPK, int argNewPosition)
{
    DisplayEntity tempe = entitylist.First(e => e.IDPK == argIDPK);
    tempe.OrderInt = argNewPosition;
    RefreshList();
}
于 2013-10-25T16:41:28.510 に答える