使用linq连接查询获取错误的输出

时间:2016-04-30 05:30:00

标签: c# .net linq join

我有这些数据:用户

UserId   Name
 42      Abc  
 43      Pqr
 44      lmn
 45      xyz

映射

MappingId  User1  User2  
1           42    43
2           42    44 
3           43    44

我想让所有user2的用户不在user 1,因此输出将在考虑上述输入的情况下显示:

预期输出

UserId   Name
 44       lmn

这是我的疑问:

var data = (from user in context.Users
                            join mappng in context.Mappings on user.UserId equals mappng.User2
                            where mappng.User1 != mappng.User2
                            select new 
                            {
                                Name = user.FirstName + " " + user.LastName,
                                UserId = user.UserId,
                            }).ToList();

但输出错误:

UserId   Name
43       Pqr
44       lmn
44       lmn

注意:没有外键关系,因此没有导航属性。

5 个答案:

答案 0 :(得分:3)

以下是控制台应用程序中问题的解决方案。我在哪里使用!(..)来查找那些不在映射User1中的那些。我不确定这种方法的其他替代方案。但希望它有所帮助。

class Program
{
    static void Main(string[] args)
    {
        List<User> users = new List<User>()
        {
            new User() { UserId = 42, Name = "Abc" },
            new User() { UserId = 43, Name = "Pqr" },
            new User() { UserId = 44, Name = "lmn" },
            new User() { UserId = 45, Name = "xyz" },
        };

        List<UserMapping> userMappings = new List<UserMapping>()
        {
            new UserMapping() { MappingId = 1, User1 = 42, User2 = 43},
            new UserMapping() { MappingId = 2, User1 = 42, User2 = 44},
            new UserMapping() { MappingId = 3, User1 = 43, User2 = 44},
        };

        var data = (from u in users
                        join m in userMappings on u.UserId equals m.User2
                        where !(from mm in userMappings
                               select mm.User1).Contains(u.UserId)
                        select u).Distinct();

        foreach(var entry in data)
        {
            Console.WriteLine(entry.UserId + " " + entry.Name);
        }

        Console.ReadLine();
    }
}

class User
{
    public int UserId { get; set; }
    public string Name { get; set; }
}

class UserMapping
{
    public int MappingId { get; set; }
    public int User1 { get; set; }
    public int User2 { get; set; }
}

输出:

44 lmn

答案 1 :(得分:2)

发布的LINQ使用User1比较同一行的User2mappng.User1 != mappng.User2值,这不是有用的查询。尝试使用!Any(),如下所示:

var data = (from user in context.Users
            join mappng in context.Mappings on user.UserId equals mappng.User2
            where !context.Mappings.Any(m => m.User1 == user.UserId)
            select new 
            {
                Name = user.FirstName + " " + user.LastName,
                UserId = user.UserId,
            }).Distinct().ToList();

答案 2 :(得分:2)

试试这个:

var data = (from map1 in context.Mappings 
            join map2 in context.Mappings 
            on map1.User2 equals map2.User1 into subMap
            from sub in subMap.DefaultIfEmpty()
            where sub == null
            join user in context.Users on map1.User2 equals user.UserId
            select new {
                 Name = user.FirstName + " " + user.LastName,
                 user.UserId,
            }).Distinct().ToList();

答案 3 :(得分:2)

请尝试剪切此代码。

var result = context.Mappings.Where(mapping1 => !context.Mappings.Select(mapping2 => mapping2.User1).Contains(mapping1.User2))
            .Select(e=> e.User2).Distinct()
            .Join(context.Users, arg => arg, user=> user.UserId,(arg,user) => user)
            .ToList();

答案 4 :(得分:2)

你可以尝试一下。

var data = (select user from context.Users where (from m2 in context.Mappings select m2.User2).Except(from m1 in context.Mappings select m1.User1).Contains(user.UserId) select new {Name=user.Name, UserId=user.UserId}).ToList();

我没有在示例表中看到user.FirstName,user.LastName。 因此,如果此解决方案有效,您可以自行修改新对象。