使用行值组合表作为列LINQ C#SQL

时间:2015-07-02 09:03:23

标签: c# sql linq

我有一个users表:

Id  | Name   | Age
-------------------- 
1   | Steve  | 21
2   | Jack   | 17
3   | Alice  | 25
4   | Harry  | 14

我还有一个包含其他用户信息的表格:

UId | Key    | Value
---------------------- 
1   | Height | 70
2   | Height | 65
2   | Eyes   | Blue
4   | Height | 51
3   | Hair   | Brown
1   | Eyes   | Green

UId列链接到Id表格中的users列。如您所见,并非所有用户都有相同的附加信息。爱丽丝没有高度值,杰克是唯一一个有眼睛颜色值的人。

有没有办法使用C#LINQ查询动态地将这些数据合并到一个表中,以便结果如下:

Id  | Name   | Age | Height | Eyes  | Hair
------------------------------------------ 
1   | Steve  | 21  |   70   | Green |     
2   | Jack   | 17  |   65   | Blue  |       
3   | Alice  | 25  |        |       | Brown   
4   | Harry  | 14  |   51   |

如果用户没有该列的值,则它可以保持为空/ null。这是否需要某种数据轮换?

5 个答案:

答案 0 :(得分:4)

对于这种情况,您的用户信息字段是常量:

Common Services

答案 1 :(得分:2)

您可以使用GroupJoin,例如:

来实现
var users = new List<Tuple<int, string, int>> {
    Tuple.Create(1, "Steve", 21),
    Tuple.Create(2, "Jack", 17),
    Tuple.Create(3, "Alice", 25),
    Tuple.Create(4, "Harry", 14)
};
var userInfos = new List<Tuple<int, string, string>> {
    Tuple.Create(1, "Height", "70"),
    Tuple.Create(2, "Height", "65"),
    Tuple.Create(2, "Eyes", "Blue"),
    Tuple.Create(4, "Height", "51"),
    Tuple.Create(3, "Hair", "Brown"),
    Tuple.Create(1, "Eyes", "Green"),
};
var query = users.GroupJoin(userInfos,
    u => u.Item1,
    ui => ui.Item1,
    (u, infos) => new { User = u, Infos = infos });
var result = query.Select(qi => new
{
    Id = qi.User.Item1,
    Name = qi.User.Item2,
    Age = qi.User.Item3,
    Height = qi.Infos.Where(i => i.Item2 == "Height").Select(i => i.Item3).SingleOrDefault(),
    Eyes = qi.Infos.Where(i => i.Item2 == "Eyes").Select(i => i.Item3).SingleOrDefault(),
    Hair = qi.Infos.Where(i => i.Item2 == "Hair").Select(i => i.Item3).SingleOrDefault()
});

答案 2 :(得分:2)

首先,我使用功能对用户详细信息数据进行了分组(我已将Key属性重命名为Feature以避免混淆)&amp; UId然后我使用组连接使用into g组合两个结果。最后使用指定的功能检索结果。

var result = from user in users
             join detail in details.GroupBy(x => new { x.UId, x.Feature })
             on user.Id equals detail.Key.UId into g
             select new
        {
           Id = user.Id,
           Name = user.Name,
           Age = user.Age,
           Height = g.FirstOrDefault(z => z.Key.Feature == "Height") != null ? 
              g.First(z => z.Key.Feature == "Height").First().Value : String.Empty,
           Eyes = g.FirstOrDefault(z => z.Key.Feature == "Eyes") != null ? 
              g.First(z => z.Key.Feature == "Eyes").First().Value : String.Empty,
           Hair = g.FirstOrDefault(z => z.Key.Feature == "Hair") != null ? 
              g.First(z => z.Key.Feature == "Hair").First().Value : String.Empty,
        };

我得到以下输出: -

enter image description here

以下是完整的Working Fiddle.

答案 3 :(得分:1)

试试这个

var list = (from u in context.users
                        join ud in context.UserDetails on u.Id equals ud.UId
                        select new
                        {
                            u.Id,
                            u.Name,
                            u.Age,
                            ud.Key,
                            ud.Value
                        });

            var finallist = list.GroupBy(x => new { x.Id, x.Name,x.Age}).Select(x => new
                {
                    x.Key.Id,
                    x.Key.Name,
                    x.Key.Age,
                    Height = x.Where(y => y.Key == "Height").Select(y => y.Value).FirstOrDefault(),
                    Eyes = x.Where(y => y.Key == "Eyes").Select(y => y.Value).FirstOrDefault(),
                    Hair = x.Where(y => y.Key == "Hair").Select(y => y.Value).FirstOrDefault()
                }).ToList();

答案 4 :(得分:0)

尝试此查询

var objlist=( form a in contex.user
              join b in contex.UserDetails on a.id equals a.Uid into gj
              from subpet in gj.DefaultIfEmpty()
                        select new { Id=a.id, Name=a.name, Age=a.age, Height =subpet.Height,Eyes=subpet.Eyes, Hair=subpet.Hair}).ToList();