linq嵌套选择新的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linq嵌套选择新的相关的知识,希望对你有一定的参考价值。
我有2个数据库表,如Family和Cars,并有一个名为Families的类。他们通过外键相互连接。
家庭
ID |姓氏|地址
汽车
ID | FamilyID |名称
一个家庭可以有多辆车。
我想将它绑定到一个网格,我写了这个查询:
var data = from d in Master.Connection.Familys.Where(x => some conditions).OrderByDescending(d => d.ID)
select new Families
{
Id = d.ID,
Surname = d.Surname,
Address = d.Address,
Cars = ""
};
foreach (var item in data)
{
var cr = Master.Connection.Cars.Where(x => x.FamilyID == item.ID);
if (!cr.Any()) continue;
foreach (var crItem in cr)
{
item.Cars += crItem.Name + ", ";
}
}
public class Families
{
public int Id { get; set; }
public string Surname { get; set; }
public string Address { get; set; }
public string Cars { get; set; }
}
网格由数据填充。但是Cars列是空的。如何在第一个查询中执行此操作?或者,有一个简单的方法来做到这一点?
答案
试试这个:
var data = from d in Master.Connection.Familys.Where(x => some conditions).OrderByDescending(d => d.ID)
select new Families
{
Id = d.ID,
Surname = d.Surname,
Address = d.Address,
Cars = ""
};
data.ForEach(f => f.Cars = String.Join(",", Master.Connection.Cars.Where(x => x.FamilyID == item.ID).Select(cr => cr.Name).ToArray()));
另一答案
你的linq正在返回IEnumerable<T>
,这是懒惰的设计。换句话说,当您执行第一个linq时,它不会立即获取数据。第一次使用时,实际上会获取数据。作为副作用,item.Cars += crItem.Name + ", ";
正在被覆盖。一种可能的解决方法是添加.ToList()
以立即获取数据。
var data = Master.Connection.Familys
.Where(x => some conditions)
.OrderByDescending(d => d.ID)
.Select(d => new Families
{
Id = d.ID,
Surname = d.Surname,
Address = d.Address,
Cars = ""
})
.ToList();
更新您的代码正在var cr = Master.Conn ... item.ID);
中对数据库进行多次调用,这是完全没必要的。相反,您可以使用GroupJoin
如下:
var data = Connection.Families //main table
.Where(x => some conditions)
.GroupJoin(Connection.Cars //left outer join
, f => f.ID //join condition
, c => c.FamilyID // join condition
, (f, c) => new {Family = f, CarNames = c.Select(o => o.Name)})
.OrderByDescending(d => d.Family.ID)
.ToList()
.Select(o => new Families
{
Id = o.Family.ID,
Surname = o.Family.SurName,
Address = o.Family.Address,
// Check possible null from left join
Cars = o.CarNames.Count() > 0 ? o.CarNames.Aggregate((a, b) => a + "," + b) : string.Empty
})
.ToList();
PS:不要使用tbean建议的.Join()
,因为.Join()
将产生INNER加入而不是LEFT OUTER加入。
另一答案
其他方式:
private IQueryable<Family> GetFamilys()
{
return Master.Connection.Familys;
}
private IQueryable<Car> GetCars()
{
return Master.Connection.Cars;
}
public List<Families> FillFamilies()
{
var list = (from family in GetFamilys()
join car in GetCars() on family.ID equals car.familyID
into groupJoin from subcar in groupJoin.DefaultIfEmpty()
select new Families
{
Id = family.ID,
Surname = family.Surname,
Address = family.Address,
Cars = subcar?.Name ?? String.Empty
}).ToList();
return list;
}
以上是关于linq嵌套选择新的的主要内容,如果未能解决你的问题,请参考以下文章
在 LINQ 中,Join 和从嵌套查询中选择第一项之间有啥区别