繁体   English   中英

实体框架+ LINQ表达式外部联接错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM