C# 如果条件仅与一个特定值匹配,则选择此选项

C# 如果条件仅与一个特定值匹配,则选择此选项,c#,linq,C#,Linq,我有一个linq查询,如果用户具有特定角色,我将尝试选择该用户的名称。但我希望它被选中,当且仅当(s)他具有仅目标特定角色,而不是其他特定角色(如总经理和采购经理) 一个用户可以在表中具有多个角色,例如同时担任“部门经理”和“总经理”。以下是表TBL_TABNET_DEF_ROLE中的示例 ID UserID RoleID 123 40 2 126 40 5 127 36 2 128 42 2 129 49 2 1

我有一个linq查询,如果用户具有特定角色,我将尝试选择该用户的名称。但我希望它被选中,当且仅当(s)他具有目标特定角色,而不是其他特定角色(如总经理和采购经理)

一个用户可以在表中具有多个角色,例如同时担任“部门经理”和“总经理”。以下是表
TBL_TABNET_DEF_ROLE
中的示例

ID UserID RoleID 
123  40    2    
126  40    5    
127  36    2    
128  42    2    
129  49    2    
130  55    2    
131  59    2    
132  61    2    
133  76    2    
134  77    2    

但是当我分配给
DepartmentManagerName
变量时,如果用户还担任“总经理”角色,我不希望分配该变量。由于“部门经理”角色早于数据库表中的“总经理”角色,where条件为true,并且用户名被分配给
DepartmentManagerName
变量,因此即使在下一次迭代中,用户也将被标识为具有“总经理”角色。但我想实现的是,如果除了“部门经理”之外,任何其他角色都匹配,那么就不会有任何任务。我怎样才能做到这一点呢?

我想用这样的方法来解决您的问题,它将获得第一个只有一个角色的用户的UserId和RoleId==2(在我的示例中)

publicstaticvoidmain()
{
var table=新列表
{
新TBL_用户(1,1,1),
新TBL_用户(2,1,2),
新的TBL_用户(3,2,1),
新的TBL_用户(5,4,1),
新的TBL_用户(6,4,2),
新的TBL_用户(7,5,1),
新TBL_用户(8,5,2),
新TBL_用户(9、5、3)
};
var user=表
.GroupBy(tbl=>tbl.UserId)//将具有相同UserId的行分组
.Where(grp=>grp.Any(u=>u.RoleId==1)和&grp.All(u=>u.RoleId!=2))//获取RoleId为1而非RoleId为2的组
.FirstOrDefault().Key;//获取第一个组并获取密钥(UserId)
}
公共类TBL_用户
{
公共int Id{get;set;}
public int UserId{get;set;}
public int RoleId{get;set;}
公共TBL_用户(int id、int用户、int角色)
{
Id=Id;
UserId=用户;
RoleId=角色;
}
}

我想到这样的方法来解决您的问题,它将获得第一个只有一个角色的用户的UserId,RoleId==2(在我的示例中)

publicstaticvoidmain()
{
var table=新列表
{
新TBL_用户(1,1,1),
新TBL_用户(2,1,2),
新的TBL_用户(3,2,1),
新的TBL_用户(5,4,1),
新的TBL_用户(6,4,2),
新的TBL_用户(7,5,1),
新TBL_用户(8,5,2),
新TBL_用户(9、5、3)
};
var user=表
.GroupBy(tbl=>tbl.UserId)//将具有相同UserId的行分组
.Where(grp=>grp.Any(u=>u.RoleId==1)和&grp.All(u=>u.RoleId!=2))//获取RoleId为1而非RoleId为2的组
.FirstOrDefault().Key;//获取第一个组并获取密钥(UserId)
}
公共类TBL_用户
{
公共int Id{get;set;}
public int UserId{get;set;}
public int RoleId{get;set;}
公共TBL_用户(int id、int用户、int角色)
{
Id=Id;
UserId=用户;
RoleId=角色;
}
}

@MongZhu,问题是linq查询逐行迭代表。为用户定义的不同角色永远不会在同一行,所以我不能在那里使用逻辑运算符。我需要在所有迭代结束后应用逻辑,然后,将检查是否有2个不同的匹配以及它们在哪里。我不知道如何将此逻辑应用于LINQ。您是否尝试过按用户ID分组,然后检查RoleId?@Guilhemprov,我不知道如何在我的问题中利用GroupBy。因此,您需要按数据分组,过滤计数大于1的数据,并获得所需的行。您需要的SQL版本是
。。。group by UserID,count(id)=1
@MongZhu,问题是linq查询逐行迭代表。为用户定义的不同角色永远不会在同一行,所以我不能在那里使用逻辑运算符。我需要在所有迭代结束后应用逻辑,然后,将检查是否有2个不同的匹配以及它们在哪里。我不知道如何将此逻辑应用于LINQ。您是否尝试过按用户ID分组,然后检查RoleId?@Guilhemprov,我不知道如何在我的问题中利用GroupBy。因此,您需要按数据分组,过滤计数大于1的数据,并获得所需的行。您需要的SQL版本是
。。。按用户id分组,计数(id)=1
我非常关心您输入的
FirstOrDefault.Property
,如果它为空,则会导致错误,在获得
FirstOrDefault
中所指的属性之前,如果
RoleId
得到保证,我是否可以建议检查
FirstOrDefault
,首先,我建议
@gablorico在RoleId列中可能永远不会有空值,但检查从来都不是一个坏选项。谢谢,我编辑了答案如果
grp.Count()==1
,您应该使用
grp.First().RoleId==2
。而且,如果有组,它保证有1个且只有一个项。@PauloMorgado如果我这样做,它可以在grp为空时触发异常。这就是我放置FirstOrDefault()的原因。RoleId我非常关心您放置的
FirstOrDefault.Property
,如果它为null,则会导致错误,在获取
RoleId
中所指的属性之前,我是否可以建议在
FirstOrDefault
上进行检查,首先,我建议
@gablorico在RoleId列中可能永远不会有空值,但检查从来都不是一个坏选项。谢谢,我编辑了答案如果
grp.Count()==1
,您应该使用
grp.First().RoleId==2
。及
ID UserID RoleID 
123  40    2    
126  40    5    
127  36    2    
128  42    2    
129  49    2    
130  55    2    
131  59    2    
132  61    2    
133  76    2    
134  77    2    
public static void Main()
{
    var table = new List<TBL_USER>
    {
        new TBL_USER(1, 1, 1),
        new TBL_USER(2, 1, 2),
        new TBL_USER(3, 2, 1),
        new TBL_USER(5, 4, 1),
        new TBL_USER(6, 4, 2),
        new TBL_USER(7, 5, 1),
        new TBL_USER(8, 5, 2),
        new TBL_USER(9, 5, 3)
    };

    var user = table
        .GroupBy(tbl => tbl.UserId) // Group the lines with the same UserId
        .Where(grp => grp.Any(u => u.RoleId == 1) && grp.All(u => u.RoleId != 2)) // Get the groups that have a RoleId as 1 and not RoleId as 2
        .FirstOrDefault().Key; // Get the first group and get the Key (UserId)
}

public class TBL_USER
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public int RoleId { get; set; }

    public TBL_USER(int id, int user, int role)
    {
        Id = id;
        UserId = user;
        RoleId = role;
    }
}