C# 用于更新提取的对象列表的Linq查询

C# 用于更新提取的对象列表的Linq查询,c#,linq,C#,Linq,我试图从另一个对象列表中提取一个列表,并且只想更新提取的列表。以下是我的代码详细信息:- public class Team { public string Id { get; set; } public Driver Driver { get; set; } public Driver Codriver { get; set; } private IList<Race> races; public virtual IEnumerable&l

我试图从另一个对象列表中提取一个列表,并且只想更新提取的列表。以下是我的代码详细信息:-

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

    private IList<Race> races;
    public virtual IEnumerable<Race> Races
    {
        get { return races; }
    }

    public virtual bool AddRace(Race newRace)
    {
        if (newRace == null) return false;
        races.Add(newRace);
        newRace.SetTeam(this);
        return true;
    }
}

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

public class Race
{
    public string Id { get; set; }
    public string Owner { get; set; }

    public virtual Team Team { get; protected set; }
    protected internal virtual void SetTeam(Team team){ Team = team; }
}

public void AssignValues(Team source, Team target)
{
    var races = source.Races.Where(race => !string.IsNullOrEmpty(race.Owner) && race.Owner == "Driver").ToList();
    races.ForEach(race => { race.Owner = "Codriver"; target.AddRace(race); });
}
公共类团队
{
公共字符串Id{get;set;}
公共驱动程序{get;set;}
公共驱动程序代码{get;set;}
私人民族;
公共虚拟可数种族
{
获取{返回比赛;}
}
公共虚拟bool AddRace(Race newRace)
{
if(newRace==null)返回false;
种族。添加(新种族);
newRace.settam(这个);
返回true;
}
}
公务舱司机
{
公共字符串DriverId{get;set;}
}
公共级别比赛
{
公共字符串Id{get;set;}
公共字符串所有者{get;set;}
公共虚拟团队{get;protected set;}
受保护的内部虚拟void settam(团队){Team=Team;}
}
公共值(团队来源、团队目标)
{
var races=source.races.Where(race=>!string.IsNullOrEmpty(race.Owner)和&race.Owner==“Driver”).ToList();
races.ForEach(race=>{race.Owner=“Codriver”;target.AddRace(race);});
}

AssignValues函数的问题是源种族也会被修改(所有者更改为Codriver),但我只想更新目标种族。有人能帮我解决这个问题吗。

这个问题与LINQ无关,而是因为您不完全了解类(即引用类型)是如何工作的。当您修改
ForEach
中的种族时,实际上是在修改
source.races
中对种族的引用
一个快速而肮脏的解决方法是创建这些对象的副本,以便原始引用保持完整:

public void AssignValues(Team source, Team target)
{
    var races = source.Races
        .Where(race => !string.IsNullOrEmpty(race.Owner) && race.Owner == "Driver")
        .Select(x => new Race 
        {
            Id = x.Id,
            Owner = x.Owner
        }
        .ToList();

    races.ForEach(race => 
    { 
        race.Owner = "Codriver"; 
        target.AddRace(race); 
    });
}

问题与LINQ无关,但与您不完全了解类(即引用类型)如何工作这一事实有关。当您修改
ForEach
中的种族时,实际上是在修改
source.races
中对种族的引用
一个快速而肮脏的解决方法是创建这些对象的副本,以便原始引用保持完整:

public void AssignValues(Team source, Team target)
{
    var races = source.Races
        .Where(race => !string.IsNullOrEmpty(race.Owner) && race.Owner == "Driver")
        .Select(x => new Race 
        {
            Id = x.Id,
            Owner = x.Owner
        }
        .ToList();

    races.ForEach(race => 
    { 
        race.Owner = "Codriver"; 
        target.AddRace(race); 
    });
}

Race
是一种引用类型(类),因此,一旦您在某处更改它,它将在引用的任何位置进行修改(在两个不同的列表中,但都包含对
Racer
的相同引用)

也许您想创建深度拷贝,例如通过:

现在,这是实现方法的最简单、最有效的方法:

public void AssignTargetRaces(Team source, Team target)
{
    var races = source.Races.Where(race => !string.IsNullOrEmpty(race.Owner) && race.Owner == "Driver");
    foreach (Race r in races)
        target.AddRace(new Race(r) {Owner = "Codriver"});
}

Race
是一种引用类型(类),因此,一旦您在某处更改它,它将在引用的任何位置进行修改(在两个不同的列表中,但都包含对
Racer
的相同引用)

也许您想创建深度拷贝,例如通过:

现在,这是实现方法的最简单、最有效的方法:

public void AssignTargetRaces(Team source, Team target)
{
    var races = source.Races.Where(race => !string.IsNullOrEmpty(race.Owner) && race.Owner == "Driver");
    foreach (Race r in races)
        target.AddRace(new Race(r) {Owner = "Codriver"});
}

这与林克无关。你必须创造新的种族

 races.ForEach(race => target.AddRace(new Race { Id = race.Id, Owner = "Codriver" });

这与林克无关。你必须创造新的种族

 races.ForEach(race => target.AddRace(new Race { Id = race.Id, Owner = "Codriver" });


实际上,这与linq无关,linq用于查询数据(这就是linq中的Q所代表的),而不是修改集合。说到这里,你可以用一个普通的
ForEach
-循环来替换你的
ForEach
-语句。@Himbrombere使用
ForEach
而不是
ForEach
不会有什么不同,实际上这与用于查询数据的linq无关(这就是linq中的Q所代表的),不用于修改集合。说到这里,你可以用一个普通的
ForEach
-循环来替换你的
ForEach
-语句。@Himbrombere使用
ForEach
而不是
ForEach
不会有什么区别,因为我的种族类中有许多其他属性。因此,不可能创建新对象并分配。您可以创建某种
Clone()
方法来创建类的克隆。您必须以某种方式创建新实例。否则您将修改原始对象。My Race类中有许多其他属性。因此,不可能创建新对象并分配。您可以创建某种
Clone()
方法来创建类的克隆。您必须以某种方式创建新实例。否则您将修改原始对象。My Race类中有许多其他属性。因此,创建新对象并分配是不可能的。另一种解决方案是将
Race
设置为
结构,而您很可能不希望这样。多少是“一个数字”?5.50?有将近40个数据成员为什么不创建一个复制构造函数来期望类的实例?当然,您必须复制40个成员中的每一个,但只能复制到构造函数中,而不是在客户端代码中的每次调用中。将构造函数添加到我的类是不可能的,因为我的类属于各种项目中引用的遗留项目。我的种族类中有许多其他属性。因此,创建新对象并分配是不可能的。另一种解决方案是将
Race
设置为
结构,而您很可能不希望这样。多少是“一个数字”?5.50?有将近40个数据成员为什么不创建一个复制构造函数来期望类的实例?当然,您必须复制40个成员中的每一个,但只能在构造函数中复制,而不是在客户端代码中的每次调用中复制。将构造函数添加到我的类是不可能的,因为我的类属于各种项目中引用的遗留项目。有没有一种方法可以从源列表中提取新列表而不使用new Race()呢@KavyaShetty:当然,你已经这么做了。但是这不会创建新的
Race
实例,这就是问题的原因。我将无法更新Race类,因为它是各种项目中引用的旧类。@KavyaShetty:那么,不要添加副本构造函数,而是手动分配属性有没有办法从