我想为通过实体框架从数据库查询数据的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,并且
DefaultIfEmpty
的integer
返回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
,因为我要加入第二个列表,该列表是List
的int
。您的情况是problem
(s),但已映射。因此,您不能在查询中构造它。这是另一个示例:
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
<== Fiddle Me ==>
关于c# - Entity Framework + LINQ表达式外部联接错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44148338/