C# 如果值不在从第二个表获取的第一个表中,则使用Linq查询连接表
我有以下结构的2个列表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
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);
}