我正在尝试从三个表中检索使用Entity Framework填充ListView的记录。
这些表的示例结构是:
luPersonType
PersonTypeID
PersonTypeDescription
人
PersonID
FirstName
LastName
{...}
PersonTypeID
EmployeeInfo
EmployeeInfoID
PersonnelNumber
StartDate
{...}
PersonID
luPersonType是一个查找表,它包含两个用于区分人员类型的值(“Customer”和“Employee”.luPersonType与People有1:M的关系。
如果某人是员工,他们将在EmployeeInfo表中存储有关他们的其他详细信息。人与EmployeeInfo有1:1(理论)关系。
示例数据:
luPersonType
PersonTypeID----PersonTypeDescription
1---------------Customer
2---------------Employee
人
PersonID----FirstName---LastName---PersonTypeID
1-----------Jane--------Doe--------1
2-----------John--------Doe--------2
3-----------Bob---------Smith------1
4-----------Sue---------Jones------2
EmployeeInfo
EmployeeInfoID----PersonnelNumber----StartDate----PersonID
1-----------------ABC123-------------1/1/13-------2
2-----------------XYZ456-------------2/1/13-------4
正如您所看到的,John和Sue都是Employees,他们每个人都有一个EmployeeInfo表中的记录。
我想返回所有人的列表,包括他们的PersonType描述和EmployeeInfo详细信息(如果有的话):
luPersonType.PersonTypeDescription,
People.LastName + ", " + People.FirstName AS FullName,
EmployeeInfo.PersonnelNumber,
EmployeeInfo.StartDate
这将导致:
PersonTypeDescription----FullName----PersonnelNumber----StartDate
Customer-----------------Doe, Jane---NULL---------------NULL
Employee-----------------Doe, John---ABC123-------------1/1/13
Customer-----------------Smith, Bob--NULL---------------NULL
Employee-----------------Jones, Sue--XYZ456-------------2/1/13
我首先尝试了这段代码,但它只返回了People和EmployeeInfo(内部联接?)中记录的人:
using(MyEntities ctx = new MyEntities())
{
var query = from a in ctx.People
join b in ctx.luPersonType on a.PersonTypeID equals b.PersonTypeID
join c in ctx.EmployeeInfo on a.PersonID equals c.PersonID
orderby a.LastName
select new
{
b.PersonTypeDescription,
FullName = a.LastName + ", " + a.FirstName,
c.PersonnelNumber,
c.StartDate
};
RadListViewPeople.DataSource = query.ToList();
}
由于这似乎导致内部联接,我研究了编写此查询的不同方法。这是我的第二次尝试:
using (MyEntities ctx = new MyEntities())
{
var query = from a in ctx.People
orderby a.LastName
select new
{
a.luPersonType.PersonTypeDescription,
FullName = a.LastName + ", " + a.FirstName,
PersonnelNumber = from b in a.EmployeeInfos
select b.PersonnelInfo
StartDate = from b in a.EmployeeInfos
select b.StartDate
}
}
这返回了所有四条记录,但它返回了PersonnelNumber(System ... String)和StartDate(System ... DateTime)的数据类型。
我已经阅读了.Include方法,但我也无法让它工作。
第二个查询给了我想要的所有记录,对我来说似乎更清晰,但我无法弄清楚如何从EmployeeInfo中检索实际数据值。
任何帮助将不胜感激!
答案 0 :(得分:1)
如果您的模型设置正确,您应该能够做到这一点(注意:未经过测试,因此我不能100%确定语法是否正确,但它应该为您提供解决问题所需的内容,我也在猜测导航属性EmployeeInfo的名称:
var query = from a in ctx.People
let b = a.EmployeeInfo.FirstOrDefault()
orderby a.LastName
select new {
a.luPersonType.PersonTypeDescription,
FullName = a.LastName + ", " + a.FirstName,
b.PersonnelNumber,
b.StartDate
};
这里的问题是PersonnelInfo实际上是1:很多,即使你只用它作为1:1,所以你必须选择第一条记录,如果没有关联则默认返回null。
注意:这仅在使用IQueryable时有效,因为EF不会将空引用视为问题。如果这被转换为IEnumerable,那么上面的代码将在PersonnelNumber和StartDate上抛出一个execption,因为对于某些记录,b将为null。