我有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列是空的。如何在第一个查询中执行此操作?或者,有一种简单的方法可以做到这一点吗?
答案 0 :(得分:1)
试试这个:
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()));
答案 1 :(得分:0)
您的linq按设计返回IEnumerable<T>
Lazy 。换句话说,当您执行第一个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加入
答案 2 :(得分:0)
另一种方式:
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;
}