MVVM ライトを使用して 2 つの関連するテーブルで DataGrid をロードする方法、私は .NET RIA と silverlight 4 を使用しています。
たとえば、私のデータテーブルが次の場合:
userInfo - userID、Name、AddressID
Address - AddressID、StreetName、Zip
[Name, StreetName, ZIP] を表示するデータグリッドを作成する方法
MVVM ライトを使用して 2 つの関連するテーブルで DataGrid をロードする方法、私は .NET RIA と silverlight 4 を使用しています。
たとえば、私のデータテーブルが次の場合:
userInfo - userID、Name、AddressID
Address - AddressID、StreetName、Zip
[Name, StreetName, ZIP] を表示するデータグリッドを作成する方法
まず、以下のように 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>
ここでは、いくつかのアプローチが可能です。思いつく両方を解説します。まず、データベースで既に定義されている関係を使用しています。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>();
}
このアプローチに関するいくつかの注意事項:
要約すると、以下が発生しない限り、最初のアプローチを使用することをお勧めします。 )。
私の経験では、メモリに追加のエンティティが読み込まれることを犠牲にしてでも、並べ替えとフィルタリングのロジックをサーバーにオフロードして、クライアントが高速な状態を維持できるようにすることで、利益が得られます。CollectionViewSource などでローカル ソートを使用しても同じことができますが、実際にアプリケーションの速度が遅くなる可能性があるのは、これらのうちのいくつかだけです。