比方说我有一个List<Person>
,其中每个人都有十几个属性。生成列表时,前十个属性都已设置。
稍后我需要填充列表中每个项目的最后两个属性的数据。
我有一个返回PersonId,Property11,Property12的存储过程,我想使用Linq从IDataReader
获取值,并从列表中填充正确Person
的值,显然在PersonId上匹配。
我从以下开始:(这不是我正在使用的实际代码,但结构类似。)
public void GetAdditionalProps( List<IPersonData> people)
{
var peopleIds = String.Join( ",", people.Select(x => x.ID));
using (var conn = Database.GetConnection(Database.PeopleDB))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "spGetPeopleData" ;
cmd.CommandType = CommandType.StoredProcedure;
cmd.AddParameterWithValue( "@Ids" , peopleIds);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var pd = people.First(p => p.ID.Equals(reader["PersonId" ]));
pd.HairColor = reader["HairColor" ].ToString();
pd.EyeColor = reader["EyeColor" ].ToString();
}
}
}
}
}
但我想知道我是否可以使用Linq来填充每个列表项的数据而无需单独找到每个列表项?
答案 0 :(得分:0)
你可以这样做......
虽然没有多少使用&#34;强迫&#34; Linq在这里......
也许加入比每次调用First()更快......
public Tuple<int,string,string> GetAdditionalData(List<IPersonData> people)
{
string peopleIds = String.Join( ",", people.Select(x => x.ID));
using (var conn = Database.GetConnection(Database.PeopleDB))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "spGetPeopleData" ;
cmd.CommandType = CommandType.StoredProcedure;
cmd.AddParameterWithValue( "@Ids" , peopleIds);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
yield return new Tuple<int,string,string>(
reader["PersonId" ],
reader["HairColor" ],
reader["EyeColor" ]);
}
}
}
}
}
public void Enrich(List<IPersonData> people)
{
var dataToEnrich = from person in people
join additional in GetAdditionalData(people)
on additional.Item1 equals person.ID
select new { Person = person,
HairColor = additional.Item2,
EyeColor = additional.Item3 };
foreach(var enrichment in dataToEnrich)
{
enrichment.Person.HairColor = enrichment.HairColor;
enrichment.Person.EyeColor = enrichment.EyeColor ;
}
}