![](/img/trans.png)
[英]Left Outer Join in Entity Framework (Linq). Member materializing to Null
[英]Entity Framework + LINQ Expression outer join error
我想为通过实体框架从数据库查询数据的linq表达式创建左外部联接。 这是linq表达式。 基本上我想做的是从问题表中的problemVehiclesTicket中搜索problem_vehicle_id,以查看是否存在,如果不存在,我想返回一个为null / empty的问题对象。 基本上我相信这是左外连接。
var ticketsDetails = (from tickets in DbContext.tickets
join problemVehiclesTicket in DbContext.problem_vehicle on tickets.tickets_id equals problemVehiclesTicket.tickets_id
join problems in DbContext.problem on problemVehiclesTicket.problem_vehicle_id equals problem.problem_vehicle_id into problemGroup
from problems in problemGroup.DefaultIfEmpty(new problem { })
where (tickets.tickets_id == ticketsId)
select new TicketsDetails
{
Ticket = tickets,
ProblemVehicle = problemVehiclesTicket,
Problems= problem,
}).ToList();
问题是反映数据库中问题表的类的类
`Problem`
id (int), description (string), type (short)
我得到的错误是“无法在LINQ to Entities查询中构造实体或复杂类型'SPOTS_Repository.speeding_offence'。” 来源来自实体框架。
任何帮助是极大的赞赏。
您所遇到的类型problem
是映射的实体。 因此,您不能在其上投影。 您可以使用匿名类型或其他非映射类(DTO)。
因为在DefaultIfEmpty
方法中您正在构造一个新problem
,它是一个映射的实体,所以不允许这样做。
固定
您不需要将任何内容传递给DefaultIfEmpty
方法。 实际上,在您的情况下,甚至不允许您这样做,因为您唯一可以通过的就是problem
并且这是映射的。 因此,使用.DefaultIfEmpty()
而不产生新的problem
。
更加困惑
这是一个示例,它将阐明DefaultIfEmpty
的用法:
选项1:无参数的DefaultIfEmpty()
var list1 = new List<int> { 1, 2, 3, 6, 4 };
var list2 = new List<int> { 4, 1, 2 };
var selection =
from l1 in list1
join l2 in list2 on l1 equals l2 into joined
from j in joined.DefaultIfEmpty()
select j;
输出: 1, 2, 0, 0, 4
为什么呢? 因为找不到3和6,并且integer
DefaultIfEmpty
返回0。
选项2:带参数的DefaultIfEmpty()
在某些情况下,我们可能希望指出,如果在联接中未找到该项目,则返回什么。 我们可以通过向DefaultIfEmpty
方法发送单个参数来做到这一点,如下所示:
var list1 = new List<int> { 1, 2, 3, 6, 4 };
var list2 = new List<int> { 4, 1, 2 };
var selection =
from l1 in list1
join l2 in list2 on l1 equals l2 into joined
from j in joined.DefaultIfEmpty(99) //<-- see this
select j;
输出: 1, 2, 99, 99, 4
为什么? 因为找不到3和6,所以在这种情况下,我们指示DefaultIfEmpty
返回99
。
请注意, DefaultIfEmpty
是通用方法。 就我而言,它需要一个int
因为我要加入第二个列表,即int
List
。 在您的情况下,这是problem
但已被映射。 因此,您不能在查询中构造它。
这是另一个示例:
var depts = new List<Department>
{
new Department { Name = "Accounting" },
new Department { Name = "IT" },
new Department { Name = "Marketing" }
};
var persons = new List<Person>
{
new Person { DeptName = "Accounting", Name = "Bob" }
};
var selection2 =
from d in depts
join p in persons on d.Name equals p.DeptName into joined2
// See here DefaultIfEmpty can be passed a Person
from j2 in joined2.DefaultIfEmpty(new Person { DeptName = "Unknown", Name = "Alien" })
select j2;
foreach(var thisJ in selection2)
{
Console.WriteLine("Dept: {0}, Name: {1}", thisJ.DeptName, thisJ.Name);
}
输出:
Dept: Accounting, Name: Bob
Dept: Unknown, Name: Alien
Dept: Unknown, Name: Alien
Public class problem()
{
public int id;
public string description;
public short type;
}
.DefaultIfEmpty(
new problem()
{
Id = ticketsId,
Description = string.empty,
});
创建类并在linq查询中使用该类,希望对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.