我如何将一行拆分为serval行?使用linq'UNION ALL'

时间:2016-07-07 11:59:34

标签: asp.net linq

1。背景

客户致电Joe因为他的应用需要打印“账单”。(〜15年前)
但“账单”根据客户类型有不同的信息。

有三种类型的客户:(a = 1,b = 2,c = 4) 客户可以是这些类型的组合。所以它是bitfield

+--------------------------------------------------------------------------------+
| id   type   is_SendA   is_SendB   is_SendC   is_PayedA   is_PayedB   is_PayedC |
+--------------------------------------------------------------------------------+
  01    1      true        true       true      true        false       false
  02    2      false       true       true      false       true        false
  03    4      false       false      false     false       false       true
  04    3      true        false      false     true        false       false
  05    3      true        true       true      false       true        false
  06    5      false       true       true      false       false       true
  07    5      false       false      false     true        false       false
  08    6      true        false      false     false       true        false
  09    7      true        true       true      false       false       true

类型:是bitfield
Is_SendA B C:保持相同的信息,但对于不同的类型,因为它们可能不同。 is_PayedA B C:保持相同的信息

论文的所有信息都乘以类型的数量。

2。我们需要什么:

由于Killing Joe不是一个选项,因此也不是drop database。
预期结果如下:

ID   type   is_Send    is_Payed
09    1       true      false
09    2       true      false
09    4       true      true

想法是让linq生成这样的东西:

SELECT   Id, 1 AS Type
        , is_SendA AS Is_Send
        , is_PayedA AS Is_Payed
WHERE    Id = 9
        AND Type & 1 = 1

UNION ALL

SELECT    Id, 2 AS Type
          , is_SendB AS Is_Send
          , is_PayedB AS Is_Payed
WHERE     Id = 9
          AND Type & 2 = 2

UNION ALL

SELECT    Id, 4 AS Type
          , is_SendB AS Is_Send
          , is_PayedB AS Is_Payed
WHERE     Id = 9
          AND Type & 4 = 4

为什么我们需要这个?因为现在要获得Paper Id = 9 Type = A,我们必须写下35列名称 在简单where id= and type=之前能够显示像show这样的内容的东西会给出正确的结果。并且能够显示一种类型的网格将能够显示另一种类型,因为列名称现在将是相同的。

有趣的事实
表中有超过90列。只有3个是唯一的,其他每个类型都是重复的 在编写列名时,Joe会遇到命名约定。有时他只是错过了打字。

Nota bene
首先,这不是代码羞辱。列的数量在这里表示将实现您可能带来的某些解决方案的复杂性 第二,有不同的命名约定这一事实说明没有办法简单地生成列名。

1 个答案:

答案 0 :(得分:2)

如果我正确理解了您的问题,您可以使用Enumerable.SelectMany()方法将您的行展开为多行,如下所示:

var results = myView.SelectMany(v =>
{
    var list = new List<Tuple<int,string>>();
    if((v.DEV_Dest & 1) == 1)
        list.Add(Tuple.Create(v.Id,v.DataA));
    if((v.DEV_Dest & 2) == 2)
        list.Add(Tuple.Create(v.Id, v.DataB));
    if((v.DEV_Dest & 3) == 3)
        list.Add(Tuple.Create(v.Id, v.DataC));
    return list;
}).ToList();