C# 如果值不在从第二个表获取的第一个表中,则使用Linq查询连接表

C# 如果值不在从第二个表获取的第一个表中,则使用Linq查询连接表,c#,linq,join,C#,Linq,Join,我有以下结构的2个列表 public class Team { public string Id { get; set; } public Driver Driver { get; set; } public Driver Codriver { get; set; } } public class Driver { public string DriverId { get; set; } } var modifiedTeams = new List<Te

我有以下结构的2个列表

public class Team
{
    public string Id { get; set; }
    public Driver Driver { get; set; }
    public Driver Codriver { get; set; }
}

public class Driver
{
    public string DriverId { get; set; }
}

var modifiedTeams = new List<Team>
{
    new Team {Id = "T1", Driver = new Driver { DriverId = "D2" }, Codriver = new Driver { DriverId = "C1"} },
    new Team {Id = "T2", Driver = new Driver { DriverId = "D1"} }
};

var allTeams = new List<Team>
{
    new Team {Id = "T1", Driver = new Driver { DriverId = "D1" }, Codriver = new Driver { DriverId = "C1"} },
    new Team {Id = "T2", Driver = new Driver { DriverId = "D2"}, Codriver = new Driver { DriverId = "C2"} }
};
有人能帮我如何通过C#中的LINQ(Lambda表达式)实现这一点吗

简单C#代码:-

List allDriverCodriverIds=new List();
foreach(修改团队中的var团队)
{
if(team.Driver!=null&!string.IsNullOrEmpty(team.Driver.DriverId))
{
添加(team.Driver.DriverId);
}
否则{
var existingTeam=allTeams.FirstOrDefault(e=>e.Id.ToString()==team.Id);
if(existingTeam!=null&&existingTeam.Driver!=null&&string.IsNullOrEmpty(existingTeam.Driver.DriverId))
{
allDriverCodriverIds.Add(existingTeam.Driver.DriverId);
}
}
if(team.Codriver!=null&&!string.IsNullOrEmpty(team.Codriver.DriverId))
{
添加(team.Codriver.DriverId);
}
其他的
{
var existingTeam=allTeams.FirstOrDefault(e=>e.Id.ToString()==team.Id);
if(existingTeam!=null&&existingTeam.Codriver!=null&&string.IsNullOrEmpty(existingTeam.Codriver.DriverId))
{
添加(existingTeam.Codriver.DriverId);
}
}
}

我正在根据您的评论编辑我的答案。请在下面查找代码

public static void KvYQ()
            {
                List<Team> modifiedTeams = new List<Team>() {
                    new Team() {
                        Id="T1"
                        ,Driver=new Driver() {
                            DriverId="D2"
                        }
                        ,Codriver=new Driver() {
                            DriverId="C1"
                        }
                    }
                    ,new Team() {
                        Id="T2"
                        ,Driver=new Driver() {
                            DriverId="D1"
                        }
                    }
                };

                List<Team> allTeams = new List<Team>() {
                    new Team() {
                        Id="T1"
                        ,Driver=new Driver() {
                            DriverId="D1"
                        }
                        ,Codriver=new Driver() {
                            DriverId="C1"
                        }
                    }
                    ,new Team() {
                        Id="T2"
                        ,Driver=new Driver() {
                            DriverId="D2"
                        }
                        ,Codriver=new Driver() {
                            DriverId="C2"
                        }
                    }
                };    

                var driverdetails = modifiedTeams.Select(x => new Team()
                {
                    Driver = x.Driver,
                    Codriver = x.Codriver

                });

                foreach (var item in driverdetails)
                {
                    Driver d = (item.Driver == null) ? allTeams.Select(x => x.Driver).FirstOrDefault() : item.Driver;
                    Driver c = (item.Codriver == null) ? allTeams.Select(x => x.Codriver).FirstOrDefault() : item.Codriver;
                    Console.WriteLine(d.DriverId + " " + c.DriverId);
                    //{D2,C1}
                    //{D1,C1}
                }


            }
publicstaticvoidkvyq()
{
List modifiedTeams=新列表(){
新团队(){
Id=“T1”
,Driver=新驱动程序(){
DriverId=“D2”
}
,Codriver=新驱动程序(){
DriverId=“C1”
}
}
,新团队(){
Id=“T2”
,Driver=新驱动程序(){
DriverId=“D1”
}
}
};
列出所有团队=新建列表(){
新团队(){
Id=“T1”
,Driver=新驱动程序(){
DriverId=“D1”
}
,Codriver=新驱动程序(){
DriverId=“C1”
}
}
,新团队(){
Id=“T2”
,Driver=新驱动程序(){
DriverId=“D2”
}
,Codriver=新驱动程序(){
DriverId=“C2”
}
}
};    
var driverdetails=modifiedTeams.Select(x=>newteam()
{
Driver=x.Driver,
Codriver=x.Codriver
});
foreach(driverdetails中的变量项)
{
驱动程序d=(item.Driver==null)?所有团队。选择(x=>x.Driver)。FirstOrDefault():item.Driver;
驱动程序c=(item.Codriver==null)?所有团队。选择(x=>x.Codriver)。FirstOrDefault():item.Codriver;
Console.WriteLine(d.DriverId+“”+c.DriverId);
//{D2,C1}
//{D1,C1}
}
}
您可以在一个查询本身中编写逻辑。但为了清楚起见,我已经用foreach写了


希望这有助于所以您希望做的是
左加入
所有团队
修改后的
团队。然后,如果左连接找到匹配的值,则取该对象的id,否则取
allTeams

var result = (from a in allTeams
             join m in modifiedTeams on a.Id equals m.Id into mj
             from m in mj.DefaultIfEmpty()
             select new Team
             {
                 Id = a.Id,
                 Driver = m?.Driver ?? a.Driver,
                 Codriver = m?.Codriver ?? a.Codriver
             }).ToList();
要仅获取ID,请执行以下操作:

var result = (from a in allTeams
              join m in modifiedTeams on a.Id equals m.Id into mj
              from m in mj.DefaultIfEmpty()
              select new [] { m?.Driver?.DriverId ?? a.Driver?.DriverId, 
                              m?.Codriver?.DriverId ?? a.Codriver?.DriverId
              }).SelectMany(i => i).ToList();

好的,显然你有一种方法来检查司机是否“不在那里”以及密码河流是否“不在那里”。虽然您没有指定驱动程序何时不存在,但从您的示例中,我推断这是在属性等于null的情况下

但让我们假设一个团队有两个功能:

bool DriverIsThere();
bool CoDriverIsThere();
现在,您有了一系列
TeamId
,您希望每个TeamId生成两个
驱动程序的
驱动程序

如果存在具有
TeamId
modifiedTeam
: 1如果
IsDriverThere()
,则生成
Driver.DriverId
,否则从
具有相同
Id
的所有团队的集合中查找
团队
,并返回
Driver.DriverId
2如果
IsCodDriverThere()
,则生成
CoDriver.DriverId
,否则从
AllTeams
集合中找到具有相同“Id”和生成“CoDriver.DriverId”的
Teadm

您没有提到如果没有具有请求的
Id
modifiedTeam
,或者如果没有具有此
Id的
AllTeams
该怎么办。假设您想抛出异常

此需求的代码可以写在一个LINQ语句中。我相信其他人也会这样回答。另一种选择是,我想推广Yield方法,因为我认为在这种情况下,它会更具可读性和可维护性

我想你的身份证是唯一的。为了增强查找,我将把修改后的团队和所有团队放入字典中,以增强查找

我不想更改您的类,所以让我们使用扩展方法

我们首先定义一下这里:

// returns true if Driver "is there"
public static bool IsThere(this Driver driver)
{
     return driver != null;
    // might be for some other reason, for instance: && !driver.IsSick
}
该功能需要一个团队,并根据上面定义的要求生成两个
驱动器
,非常简单:

public static IEnumerable<string> ToDriverIds(this Team team,
    Dictionary<string, Team> allTeams)
{
    if (team.Driver.IsThere())
        // Driver is there, yield return the Id
        yield return team.Driver.DriverId;
    else
    {   // Driver not available, fetch the Driver from allTeams
        // throw exception if there is no alternative team with this team ID
        Team alternativeTeam = allTeams[team.Id];
        if (alternativeTeam.IsDriverThere())
            yield return alternativeTeam.Driver.Id;
        else
           // Driver also not in alternative team: exception
           throw new InvalidOperationException("...");

        // do the same for coDriver
    }
}
公共静态IEnumerable TodriverID(此团队,
字典(所有团队)
{
if(team.Driver.IsThere())
//司机在那里,请返回Id
收益返回team.Driver.DriverId;
其他的
{//驱动程序不可用,请从所有团队获取驱动程序
//如果没有具有此团队ID的备选团队,则抛出异常
团队备选团队=所有团队[Team.Id];
// returns true if Driver "is there"
public static bool IsThere(this Driver driver)
{
     return driver != null;
    // might be for some other reason, for instance: && !driver.IsSick
}
public static IEnumerable<string> ToDriverIds(this Team team,
    Dictionary<string, Team> allTeams)
{
    if (team.Driver.IsThere())
        // Driver is there, yield return the Id
        yield return team.Driver.DriverId;
    else
    {   // Driver not available, fetch the Driver from allTeams
        // throw exception if there is no alternative team with this team ID
        Team alternativeTeam = allTeams[team.Id];
        if (alternativeTeam.IsDriverThere())
            yield return alternativeTeam.Driver.Id;
        else
           // Driver also not in alternative team: exception
           throw new InvalidOperationException("...");

        // do the same for coDriver
    }
}
public static Driver ToDriver(this Team team,
    Dictionary<string, Team> allTeams,
    Func<Team, Driver> driverSelector)
{
    Driver driver = driverSelector(team);
    if (driver.IsThere())
        return driver.Id;
    else
    {   // use allTeams:
        Team allternativeTeam = allTeams[team.Id];
        driver = friverSelector(alternativeTeam);
        if (driver.IsThere())
            return driver.Id;
        else
            throw new InvalidOperationException(...);
    }
}
public static IEnumerable<string> ToDriverIds(this Team,
   Dictionary<string, Team> allTeams)
{
    // return the driverId of the driver:
    yield return Team.ToDriverId(allTeams, team => team.Driver);
    // yield return the driverId of the CoDriver:
    yield return Team.ToDriverId(allTeams, team => team.CoDriver);
}
public static IEnumerable<string> ToDriverIds(this string teamId,
    Dictionary<string, Team> modifiedTeams
    Dictionary<string, Team> allTeams)
{
    return modifiedTeams[teamId].ToDriverids(allTeams);
    // exception if there is no team with teamId
}
public static IEnumerable<string> ToIds(this IEnumerable<string> teamIds,
   IEnumerable<Team> modifiedTeams, IEnumerable<Team> allTeams)
{
    var modifiedTeamsLookup = modifiedTeams.ToDictionary(team => team.Id);
    var allTeamsLookup = allTeams.ToDictionary(team => team.Id);

    return teamIds
        .SelectMany(teamId => teamId.ToDriverIds(modifiedTeamsLookup,
            allTeamsLookup);

}