0

3 つのテーブル (私がやろうとしていることへの単純化されたアプローチ) を使用して、動的列を使用してテーブルを作成しようとしています。

レイアウトは、各所有者が持っているライセンスを示すグリッドにする必要があります。これは、テーブルのヘッダー列を取得するために最初に個別の選択を行う必要があるテーブルから取得されます。

ここに画像の説明を入力

動的列を取得するために、テーブルのヘッダーを取得する方法は次のとおりです

var tableHeader = (from l in Licenses
join lt in LicenseTypes on l.LicenseTypeId equals lt.ID
where l.Category == 1
select new 
{
    l.LicenseTypeId,
    lt.Name
}).Distinct().OrderBy (x =>x.Name )

ここに画像の説明を入力

このクエリをヘッダークエリと一緒に使用してテーブルを作成する最善の策が何であるかがよくわかりません

var tableData = (from l in Licenses select l)

1 つの方法は、tableData を繰り返し、個別の所有者ごとにデータ行を作成し、所有者名などのデータを取得してグリッドに表示するサブクエリを作成することです。ただし、これによりデータベースへの一連のトランザクションが発生するため、これをよりエレガントな方法で行うことができるかどうか疑問に思っています。

私の例のデータを生成するためのスクリプトは次のとおりです。

if exists (select * from sysobjects where name = 'LicenseType') drop table LicenseType
if exists (select * from sysobjects where name = 'License') drop table License
if exists (select * from sysobjects where name = 'LicenseOwner') drop table LicenseOwner
go

create table LicenseType
(
    ID int not null primary key,
    Name nvarchar(30) not null
)

create table LicenseOwner
(
    ID int not null primary key,    
    Name nvarchar(30) not null
)

create table License
(
    ID int not null primary key,
    LicenseTypeId int null references LicenseType(ID),
    LicenseOwnerId int null references LicenseOwner(ID),
    Status nvarchar(30),
    Category int not null
)

insert LicenseType values (1, 'A001')
insert LicenseType values (2, 'A002')
insert LicenseType values (3, 'A003')
insert LicenseType values (4, 'A004')
insert LicenseType values (5, 'C001')
insert LicenseType values (6, 'X001')

insert LicenseOwner values (1, 'Owner 1')
insert LicenseOwner values (2, 'Owner 2')
insert LicenseOwner values (3, 'Owner 3')
insert LicenseOwner values (4, 'Owner 4')
insert LicenseOwner values (5, 'Owner 5')

insert License values (1, 1, 1, 'OK', 1)
insert License values (2, 2, 1, 'Invalid', 1)
insert License values (3, 3, 1, 'OK', 1)
insert License values (4, 6, 1, 'Pending', 1)
insert License values (5, 1, 1, 'OK', 1)
insert License values (6, 2, 1, 'OK', 1)
insert License values (7, 6, 1, 'Invalid', 1)
4

1 に答える 1

1

データテーブルに満足している場合は、次のようなことができます。

var data = (from r in Licenses 
            where r.Category == 1
            select new 
            { 
                 Owner       = r.LicenseOwner.Name , 
                 LicenseType = r.LicenseType.Name,  
                 Status      = r.Status 
            }
            ).ToList();

これにより、1 回のデータベース ルックアップで必要なすべての情報が取得され、必要に応じてフィルター処理できます (カテゴリ 1 のみを選択する例のように)。

次に、ToLookup を使用して、すべての (メモリ内の) レコードを所有者別にグループ化できます。つまり、

var lookup = data.ToLookup(r => r.Owner , 
                           r => new   
                              { 
                              License = r.LicenseType  , 
                              Status = r.Status
                              } 
                           ).OrderBy(r=>r.Key);

次に、列名を取得し、そこからデータテーブルを構築します。

var columns = (from r in data 
                    orderby r.LicenseType 
                    select r.LicenseType
                  ).Distinct().ToList();

DataTable dt = new DataTable();
dt.Columns.Add("Owner");
foreach(var r in columns)
    dt.Columns.Add(r);

次に、ルックアップからデータテーブルを作成します

foreach(var r in lookup)
{
    DataRow dr = dt.NewRow();
    dr["Owner"]  = r.Key ;

    foreach(var column in columns)
        dr[column] = "";

    foreach(var entry in r)
        dr[entry.License] = entry.Status;
    dt.Rows.Add(dr);
}

また、System.Data.DataSetExtensions への参照を含めると、linq を使用して結果のデータテーブルをクエリできます。

 var owner1 = (from r in dt.AsEnumerable() 
                  where r.Field<string>("Owner") == "Owner 1"      
                  select r
              ).SingleOrDefault();
于 2012-11-28T19:58:01.013 に答える