.Net Linq DataSet问题(左外连接)

时间:2009-09-22 02:16:46

标签: c# .net linq dataset

我有3个sql表SourceKeys,Channels和ChannelTypes。查询这些表,并将其数据存储在我的数据集中的数据表中。

我需要的是:

SELECT ...
FROM ChannelTypes ct 
LEFT OUTER JOIN Channels ch ON ct.channelTypeID = channelTypeID
LEFT OUTER JOIN SourceKeys sk ON ch.channelID = sk.channelID

但是以linq形式...我对linq有点新鲜并且阅读了一些msdn文章,但只是需要一些帮助才能克服困难。

var sourceKeyQuery = 
    from ct in ds.Tables["ChannelTypes"].AsEnumerable()
     join ch in ds.Tables["Channels"].AsEnumerable()
     on ct.Field<int>("channelTypeID") equals ch.Field<int>("channelTypeID") into gj1
     from channels in gj1.DefaultIfEmpty()
     join sk in ds.Tables["SourceKeys"].AsEnumerable()
     on channels.Field<int>("channelID") equals sk.Field<int>("channelID") into gj2
     from sourceKeys in gj2.DefaultIfEmpty()
     orderby ct.Field<string>("channelType"), 
             channels.Field<string>("channel"),
             sourceKeys.Field<string>("sourceKeys")
     select (sourceKeys == null)?null:sourceKeys.Field<int?>("sourceKeyID");

我收到的错误channels.Field<int>("channelID")不能为空...我尝试使用<int?>但它没有用。

2 个答案:

答案 0 :(得分:2)

FWIW,我发现代码比对DataTable.Select的简单调用更难理解,如果需要,它还允许通过父表或子表进行过滤和排序。

var keys = ds.Tables["SourceKeys"].Select(...)
foreach (var key in keys)
{
    int id = key["sourceKeyID"];
    ...
} 

当然,假设您在表之间定义了DataRelation

我唯一不能100%确定你能做的就是在Select方法中按频道排序,因为该表似乎是源键的兄弟,而不是父/子关系。

编辑:您可能要考虑的其他方法:如果您确实有(嵌套)数据关系,那么可能是DataSet.GetXml()然后使用LinqToXml进行查询?

答案 1 :(得分:2)

我混淆了一些东西......看起来这样可行。

var sourceKeyQuery = from ct in ds.Tables["ChannelTypes"].AsEnumerable()
                     join ch in ds.Tables["Channels"].AsEnumerable()
                     on ct.Field<int>("channelTypeID") equals ch.Field<int>("channelTypeID") into g_ch
                     join sk in ds.Tables["SourceKeys"].AsEnumerable()
                     on ct.Field<int>("channelTypeID") equals sk.Field<int>("channelID") into g_ct
                     from ch in g_ch.DefaultIfEmpty()
                     from sk in g_ct.DefaultIfEmpty()
                     select new 
                     {
                         channelTypeID = ct.Field<int>("channelTypeID"),
                         channelType = ct.Field<string>("channelType"),
                         channelID = (ch == null)?null:ch.Field<int?>("channelID"),
                         channel = (ch == null)?String.Empty:ch.Field<string>("channel"),
                         sourceKeyID = (sk == null)?null:sk.Field<int?>("sourceKeyID"),
                         sourceKey = (sk == null)?String.Empty:sk.Field<string>("sourceKey")
                     };