我想为通过实体框架从数据库查询数据的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,并且DefaultIfEmptyinteger返回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,因为我要加入第二个列表,该列表是Listint。您的情况是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/

10-13 05:50