0

MVVM ライトを使用して 2 つの関連するテーブルで DataGrid をロードする方法、私は .NET RIA と silverlight 4 を使用しています。

たとえば、私のデータテーブルが次の場合:

userInfo - userID、Name、AddressID
Address - AddressID、StreetName、Zip

[Name, StreetName, ZIP] を表示するデータグリッドを作成する方法

4

2 に答える 2

1

まず、以下のように DomainService クラスの UserInfo の GetQuery に Address テーブルを含める必要があります...

  [Query]
  public IQueryable<UserInfo> GetUserInfos()
    {
        return this.ObjectContext.UserInfos.Include("Address");
    }

次に、メタデータ ファイルのすぐ上に [Include] を追加する必要があります。

  [Include]
        public Addresses Address{ get; set; }
        public int AddressID { get; set; }

ソリューションをビルドします。Xamlでは、このように使用できます

  <sdk:DataGrid ItemsSource="{Binding UserList, Mode=TwoWay}" SelectedItem="{Binding CurrentUser, Mode=TwoWay}" Margin="0,0,0,2" AutoGenerateColumns="False">
        <sdk:DataGrid.Columns>
            <sdk:DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
            <sdk:DataGridTextColumn Header="Street Name" Binding="{Binding Path=Address.StreetName}"/>
            <sdk:DataGridTextColumn Header="Zip" Binding="{Binding Path=Address.Zip}"/>
        </sdk:DataGrid.Columns>

    </sdk:DataGrid>
于 2012-02-28T09:14:21.920 に答える
0

ここでは、いくつかのアプローチが可能です。思いつく両方を解説します。まず、データベースで既に定義されている関係を使用しています。2 つ目は、カスタム モデル クラスを介して返すことです。

オプション 1: Web プロジェクトのデータベースから Entity Framework モデル (リレーションシップを含む) を作成し、モデルをホストする DomainService を作成したと仮定します。!!!モデルを作成するときに重要なことは、モデルのメタデータ クラスを作成することです!!! (最初の数回はこれを見逃していました。ここで必要なように、モデルの動作を変更することが重要です)

メタデータ モデル内で関連付けプロパティが見つかり、[Include] 属性で装飾されます。これは、関連する割り当てを返したい WorklanDetail を持つ別のプロジェクトからの例です。

[MetadataTypeAttribute(typeof(WorkplanDetailMetadata))]
public partial class WorkplanDetail
{
    internal sealed class WorkplanDetailMetadata
    {
        [Include]
        public EntityCollection<Assignment> Assignments { get; set; }
    }
}

その後、Silverlight アプリケーションでプロパティを参照するだけで、住所データが利用可能になります。

単一のエンティティ(コレクションではなくEntityReference)をバインドするには、プロパティを使用してデータグリッドのバインディングのサブエンティティにアクセスします...例:

Text="{Binding Path=Address.StreetName}"

それは私が知っている最も簡単な方法です。

オプション 2 では、独自のカスタム クラスを作成する必要があります (クライアントとの間の転送を容易にするために、少なくとも [Key] 属性で装飾されたプロパティが必要です)。例を次に示します。フォルダー検索結果情報を取得するために使用しました。

public class FolderSearchResult
{
    [Key]
    public string EFOLDERID { get; set; }
    public string Subject { get; set; }
    public string FolderName { get; set; }
}

鍵となるのは、EFOLDERID プロパティに [Key] 属性があり、データベース内の PK のように各アイテムを一意に識別することです。

次に、サービスクラスで、このようなものを次のように返すことができます:

public IEnumerable<FolderSearchResult> GetFolderResults(string search)
    {
        var query = from ge in this.ObjectContext.Generic_Engagement
                    from f in this.ObjectContext.eFolders
                    where ge.EFOLDERID == f.eFolderID &
                    f.eArchived == 0 &
                    f.eSubject.Contains(search) &

                    (from wp in this.ObjectContext.Workplans
                     where wp.EFOLDERID == f.eFolderID
                     select wp).Count() == 0 &

                     (from r in this.ObjectContext.Resources
                      where r.EFOLDERID == f.eFolderID
                      select r).Count() == 0

                    select new FolderSearchResult()
                      {
                        EFOLDERID = f.eFolderID,
                        FolderName = f.eFolderName,
                        Subject = f.eSubject
                      };
        return query.AsEnumerable<FolderSearchResult>();
    }

このアプローチに関するいくつかの注意事項:

  1. 私の意見では、これは読み取り専用アクセスが必要ない場合に最適です。更新/挿入/削除を行っている場合は、最初のアプローチを使用してください。
  2. これは、完全に異なるデータ ソース (データベースのユーザー ID と従業員 ID、Active Directory の表示名、サイトの場所など) 間で何らかの論理オブジェクトを作成する必要がある場合に役立ちます。
  3. この方法で更新することは可能ですが、アイテムを分離してすべてを適切に更新するには、もう少し作業を行う必要があります。

要約すると、以下が発生しない限り、最初のアプローチを使用することをお勧めします。 )。

私の経験では、メモリに追加のエンティティが読み込まれることを犠牲にしてでも、並べ替えとフィルタリングのロジックをサーバーにオフロードして、クライアントが高速な状態を維持できるようにすることで、利益が得られます。CollectionViewSource などでローカル ソートを使用しても同じことができますが、実際にアプリケーションの速度が遅くなる可能性があるのは、これらのうちのいくつかだけです。

于 2010-07-20T18:45:59.077 に答える