嵌套的 foreach 循环,对实体框架有副作用



由于以下示例,我对嵌套的foreach循环有问题:

var someList = new List<SimpleC>();
simpleA = database.SimpleA.ToList();
simpleB = database.SimpleB.ToList();
foreach (var a in simpleA)
{
foreach (var b in simpleB)
{
var c = new simpleC();
c.simpleAId = a.Id;
c.simpleAName = a.Name;
c.simpleBName = b.Name;
someList.Add(c);
}
}
return someList;

问题:想象一下,第一次迭代它转到第一个 foreach 循环,然后转到第二个 foreach 循环,它启动新对象,映射值并将新启动的对象添加到新列表中,但是当第二次迭代到来而不是返回到第一个 foreach 循环时,它继续第二个 foreach 循环,它循环通过第二个循环直到完成, 我知道这就是 C# 的工作方式,但我需要副作用才能让它继续首先 foreach 循环以获取新值。

最好不要尝试手动迭代它,建立关系并将其作为实体的联接集进行查询:

var results = database.SimpleA 
.Join(database.SimpleB, 
a => a.ID,       
b => b.Post_ID,   /
(a, b) => new { colA = a, colB = b }) 
.Select new SimpleA(){
Property1 = a.Col1,
Property2 = b.Col3,
Property4 = a.Col2
}).ToList(); 

这主要只是作为起点的功能。您可能需要左外部联接。

另一个选项是,如果 A 和 B 在数据库中具有 fk 约束,则可以使用导航属性而不是联接。

如果出于任何原因需要您的循环,我们可以尝试分解问题:

foreach (var a in simpleA)
{
foreach (var b in simpleB)  // There is no relationship here!
{
var c = new simpleC();
c.simpleAId = a.Id;
c.simpleAName = a.Name;
c.simpleBName = b.Name;
someList.Add(c);
}
}

您可以尝试使用该索引,但这很可能会导致问题。

相反:

foreach (var a in simpleA)
{
var matchedB = simpleB.Where(x => x.Id == a.Id).FirstOrDefault();
var c = new simpleC();
c.simpleAId = a.Id;
c.simpleAName = a.Name;
c.simpleBName = matchedB.Name;
someList.Add(c);
}

我想,如果我理解你的问题,你不希望它以嵌套的方式循环,而只循环一次。要做到这一点,你会这样做。

for(int i = 0; i < simpleA.Count; i++)
{
var c = new simpleC();
c.simpleAId = simpleA[i].Name;
c.simpleAName = simpleA[i].Name;
c.simpleBName = simpleB[i].Name;
someList.Add(c);
}

最新更新