带外连接的Linq查询不会返回预期结果

时间:2017-05-25 20:10:10

标签: vb.net linq linq-to-objects

这可能很简单,但我无法做到。 这是我的布线 - 事件与规则有多对多的关系。活动可能有也可能没有规则。规则将有自己的细节。最重要的是,我需要一个像这样的对象:

  

对象
           - 事件
           - 规则(null)
           - 映射列表(null)

所以,我将这些关系硬编码为

Dim eventList As new List(Of [Event])
eventList.Add(new [Event]() With {.EventId = 1, .ClassId = 1, .TypeId = 1, .EventSequence = 2}) ' this is event without rules
eventList.Add(new [Event]() With {.EventId = 2, .ClassId = 1, .TypeId = 1, .EventSequence = 1})
eventList.Add(new [Event]() With {.EventId = 3, .ClassId = 1, .TypeId = 1, .EventSequence = 3})


Dim ruleEventList As New List(Of RuleEvent)
ruleEventList.Add(new RuleEvent() With {.Id = 1, .EventId = 2, .RuleId = 1})
ruleEventList.Add(new RuleEvent() With {.Id = 2, .EventId = 3, .RuleId = 1})


Dim ruleList As New List(Of Rule)
ruleList.Add(new Rule() With {.Id = 1, .EntityId = 1, .SearchId = 1})


Dim ruleDetailList As New List(Of RuleDetail)
ruleDetailList.Add(new RuleDetail() With {.Id = 1, .RuleId = 1, .Value = "aaa"})
ruleDetailList.Add(new RuleDetail() With {.Id = 2, .RuleId = 1, .Value = "bbb"})

这似乎是正确的,因为2/3正常工作。但这是LINQ

Dim eventRuleDetailList = _
    From ev In eventList
    From re In ruleEventList.Where(Function(r) r.EventId = ev.EventId).DefaultIfEmpty()
    From rule In ruleList.Where(Function(r) re IsNot Nothing AndAlso r.Id = re.RuleId).DefaultIfEmpty()
    From det In ruleDetailList.Where(Function(r) rule IsNot Nothing AndAlso r.RuleId = rule.Id).DefaultIfEmpty()
    Group ev, rule, det By ev.EventId, ev.ClassId, ev.TypeId, ev.EventSequence
        Into g = Group
    Order By ClassId, TypeId, EventSequence
    Select New With
        {
            .EventId = EventId,
            .Event = g.First().ev,
            .Rule = g.First().rule,
            .Details = g.Select(Function(itm) itm.det) '<-- This is my glitch 
        }

结果似乎几乎正确,但有一个问题。我似乎无法得到&#34;细节&#34;右

For Each erd In eventRuleDetailList
    Console.WriteLine("Event Id: {0}; Event Seq: {1}; Rule Id: {2}; Details: {3}", 
        erd.EventId, 
        erd.Event.EventSequence, 
        If (erd.Rule Is Nothing,  "No Rules", erd.Rule.Id),
        If (erd.Details Is Nothing,  "No Details",  "Yes Details")
    )

Next 

输出:

  

事件ID:2;事件序列:1;规则ID:1;详情:是详情
  事件编号:1;事件序列:2;规则ID:无规则;详情:是详情
  事件编号:3;事件序列:3;规则ID:1;已映射的详细信息:是详细信息

这是问题所在。我做错了,因为Event Id: 1应该说&#34;没有细节&#34;。它有&#34;没有规则&#34;

由于

2 个答案:

答案 0 :(得分:0)

以与规则相同的方式表明详细信息:

            .Rule = g.First().rule,
            .Details = g.First().det,

答案 1 :(得分:0)

我得到了它的工作

以下是需要稍加调整的Select New With { .EventId = EventId, .Event = g.First().ev, .Rule = g.First().rule, .Details = if(g.First().rule is nothing, nothing, g.Select(Function(itm) itm.det)) }

{{1}}

输出

  

事件ID:2;事件序列:1;规则ID:1;详情:是详情
  事件编号:1;事件序列:2;规则ID:无规则;细节:没有细节
  事件编号:3;事件序列:3;规则ID:1;已映射的详细信息:是详细信息