简体   繁体   English

包含/合并问题的实体框架

[英]Entity Framework with Include / Joining Issues

I've implemented an Table Inheritance functionality demonstrated at http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server . 我已经实现了在http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server中演示的表继承功能。

All the foreign keys and constraints are in place. 所有外键和约束都到位。

Now I am using Entity Framework to pull back my People, Students, Teachers, and Parents where the model looks something like the following (without all the EF specific attributes etc). 现在,我使用实体框架来拉回我的人员,学生,教师和家长,其中模型看起来类似于以下内容(没有所有EF特定属性等)。

public partial class People : EntityObject
{
  public guid PeopleID { get; set; }
  public int Age { get; set; }  /Added for an example query
  public PeopleParent Parent { get; set; }
  public PeopleStudent Student { get; set; }
  public PeopleTeacher Teacher { get; set; }
}

Now I need to get all People regardless of type, who are 25 years old, no more than 100 records, and I want to include all the referenced data. 现在,我需要获取25岁以下,不超过100条记录的所有不分类型的人员,并且我想包括所有引用的数据。 I create my EF Query like: 我创建我的EF查询,如下所示:

IQueryable<People> query = Entities.People.Include("PeopleParent")
                                           .Include("PeopleStudent")
                                           .Include("PeopleTeacher");

query.Where(x => x.Age == 25)
     .Take(100);

IEnumerable<People> results = query.ToList();

Seems simple enough, but whatever table/entityset I've set to include first creates an INNER JOIN instead of the LEFT OUTER JOIN , which is not producing the right results. 看起来很简单,但是无论我设置要包含的任何表/实体集都首先创建一个INNER JOIN而不是LEFT OUTER JOIN ,这不会产生正确的结果。

Generated TSQL (incorrect for my needs): 生成的TSQL(对于我的需求而言不正确):

SELECT 
  [Limit1].[C1] AS [C1],
  <A bunch of Limit1 Columns>
FROM (
  SELECT TOP (100) 
    [Extent1].[PeopleID] AS [PeopleID],
    <A bunch of Extent1 Columns>
    [Extent2].[PeopleID] AS [PeopleID1], 
    <A bunch of Extent2 Columns>
    [Extent3].[PeopleID] AS [PeopleID2], 
    <A bunch of Extent3 Columns>
    [Extent4].[PeopleID] AS [PeopleID3], 
    <A bunch of Extent4 Columns>
    1 AS [C1]
  FROM [rets].[People] AS [Extent1]
  INNER JOIN [rets].[PeopleParent] AS [Extent2] 
    ON [Extent1].[PeopleID] = [Extent2].[PeopleID]
  LEFT OUTER JOIN [rets].[PeopleStudent] AS [Extent3] 
    ON [Extent1].[PeopleID] = [Extent3].[PeopleID]
  LEFT OUTER JOIN [rets].[PeopleTeacher] AS [Extent4] 
    ON [Extent1].[PeopleID] = [Extent4].[PeopleID]
) AS [Limit1]

Why is the first Include used as an INNER JOIN , and is there a soluion to my problem? 为什么第一个Include用作INNER JOIN ,我的问题有解决方案吗?

** UPDATE 1** **更新1 **

Assuming I use Ladislav Mrnka's Answer , there are two additional requirements due to the significant change in Linq and Lambda querying. 假设我使用Ladislav Mrnka的Answer ,由于Linq和Lambda查询的重大变化,还有两个其他要求。

Question: How do I search for specific People which have specific properties? 问题:如何搜索具有特定属性的特定人员?

(All Students with a Grade of "A") (所有成绩为“ A”级的学生)

Answer: 回答:

context.People.OfType<Student>().Where(s => s.Grade == "A");

Question: How do I search for any People that have a specific property? 问题:如何搜索具有特定财产的任何人?

(All Students or Teachers who's PrimaryFocus = "Math") (所有主要焦点=“数学”的学生或老师)

Answer: 回答:

List<People> result = new List<People>();
result.AddRange(context.People.OfType<Student>()
                              .Where(x => x.PrimaryFocus == "Math")
                              .ToList());
result.AddRange(context.People.OfType<Teacher>()
                              .Where(x => x.PrimaryFocus == "Math")
                              .ToList());

The obvious solution for you should be using native EF support for inheritance. 对于您而言,显而易见的解决方案应该是使用本机EF支持进行继承。 In your case TPT inheritance . 您的情况是TPT继承 Once you have inheritance you will simply call: 继承后,您只需调用:

IEnumerable<People> results = Entities.People
                                      .Where(x => x.Age == 25)
                                      .Take(100)
                                      .ToList();

And it will return you instances of Student , Teachers , Parents etc. 它将返回您的实例StudentTeachersParents等。

In your solution the only advice is check that the relation is optional (1 - 0..1) - . 在您的解决方案中,唯一的建议是检查该关系是否为可选(1-0..1)-。 If it is required it will use INNER JOIN . 如果需要,它将使用INNER JOIN If it is optional and it still uses INNER JOIN it can be some bug or other problem in your model. 如果它是可选的,但仍使用INNER JOIN则可能是模型中的错误或其他问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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