Linq查询结果到具有动态cols的表

时间:2012-11-26 14:08:14

标签: linq linq-to-entities

有三个表(我试图做的简化方法)我正在尝试用动态cols构建一个表。

布局应该是一个网格,显示每个所有者拥有的许可证。这是从一个表中检索的,我首先需要做一个不同的选择来获取我表的标题列。

enter image description here

以下是我如何检索表格的标题,以获取动态列

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 )

enter image description here

我不太清楚我最好的选择是将这个查询和我的headerquery一起用来组成我的表格

var tableData = (from l in Licenses select l)

一种方法是迭代tableData,并为每个不同的所有者构建数据行,并使子查询返回诸如Owners name之类的数据以在网格中显示。然而,这将导致数据库的一系列事务,所以我想知道这是否可以以更优雅的方式完成。

这是一个为我的例子生成数据的脚本:

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)

1 个答案:

答案 0 :(得分: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)

然后,您可以使用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();