【问题标题】:.Net Linq DataSet Problems (left outer joins).Net Linq 数据集问题(左外连接)
【发布时间】:2010-11-30 06:42:26
【问题描述】:

我有 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&lt;int&gt;("channelID") 不能为空...我尝试使用 &lt;int?&gt; 但它没有用。

【问题讨论】:

    标签: c# .net linq dataset


    【解决方案1】:

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

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

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

    我不能 100% 确定您能做的唯一事情是在 Select 方法中按通道排序,因为该表似乎是源键的同级,而不是父/子关系。

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

    【讨论】:

    • 我确实有数据关系设置,请检查一下
    • 我将来会使用它,但只有在 sourcekey 数据表行存在时才会返回记录(我相信)......我正在使用它来填充树视图,所以我需要通道类型和通道即使没有源密钥存在
    • 啊...很公平,但是 ds.Tables["ChannelTypes"].Select(..) 还不够吗?无论如何,你把它排序了:)
    【解决方案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")
                         };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多