首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在实体框架linq中两次包含相同字段时的行为

在实体框架linq中两次包含相同字段时的行为
EN

Stack Overflow用户
提问于 2016-10-26 14:52:52
回答 3查看 987关注 0票数 6

当我两次包含同一个字段时会发生什么,这意味着我从db获取一个实体,并使用EF .include选项。我的意思是:

我有:

代码语言:javascript
复制
.Include(x => x.Student)
.Include(x => x.Car)
.Include(x => x.Student)

这就是模式:

代码语言:javascript
复制
Person has a Student
Person has a car

因此,如果(错误地)将学生包括两次(因为我的人只有一个学生),有问题吗?

我只想把它包括一次!因为我只有一个学生。他抱怨这事吗?我试过了,看起来没问题,但我不知道这意味着什么。有人能解释/详细说明吗?搜索了一下,但找不到任何问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-26 15:17:07

取此样本:

代码语言:javascript
复制
public class RentContext : DbContext
{
    public DbSet<Student> Students { get; set; }

    public DbSet<Rent> Rents { get; set; }

    public DbSet<Car> Cars { get; set; }
}

public class Car
{
    public int Id { get; set; }

    public string Model { get; set; }

    public double Price { get; set; }
}

public class Rent
{
    public int Id { get; set; }

    public Student Student { get; set; }

    public Car Car { get; set; }
}

public class Student
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int Year { get; set; }
}

租金包括学生和汽车。

让我们使用唯一的包含子句进行查询:

代码语言:javascript
复制
var rents = ctx.Rents
    .Include(x => x.Student)
    .Include(x => x.Car)
    //.Include(x => x.Student)
    .ToList();

这是生成的sql:

代码语言:javascript
复制
SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name],
[Extent2].[Year] AS [Year],
[Extent3].[Id] AS [Id2],
[Extent3].[Model] AS [Model],
[Extent3].[Price] AS [Price]
FROM   [dbo].[Rents] AS [Extent1]
LEFT OUTER JOIN [dbo].[Students] AS [Extent2] ON [Extent1].[Student_Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Cars] AS [Extent3] ON [Extent1].[Car_Id] = [Extent3].[Id]

让我们创建一个复制包含的查询:

代码语言:javascript
复制
var rents = ctx.Rents
    .Include(x => x.Student)
    .Include(x => x.Car)
    .Include(x => x.Student)
    .ToList();

您将得到以下sql:

代码语言:javascript
复制
SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name],
[Extent2].[Year] AS [Year],
[Extent3].[Id] AS [Id2],
[Extent3].[Model] AS [Model],
[Extent3].[Price] AS [Price]
FROM   [dbo].[Rents] AS [Extent1]
LEFT OUTER JOIN [dbo].[Students] AS [Extent2] ON [Extent1].[Student_Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Cars] AS [Extent3] ON [Extent1].[Car_Id] = [Extent3].[Id]

如您所见,EF非常聪明,即使您不止一次指定包含,也可以生成相同的sql。

更新:重复包含(多次)

让我们试试这个:

代码语言:javascript
复制
var rents = ctx.Rents
    .Include(x => x.Student)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Car)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .Include(x => x.Student)
    .ToList();

重复包括和多次。下面是生成的sql:

代码语言:javascript
复制
SELECT
    [Extent1].[Id] AS [Id],
    [Extent2].[Id] AS [Id1],
    [Extent2].[Name] AS [Name],
    [Extent2].[Year] AS [Year],
    [Extent3].[Id] AS [Id2],
    [Extent3].[Model] AS [Model],
    [Extent3].[Price] AS [Price]
    FROM   [dbo].[Rents] AS [Extent1]
    LEFT OUTER JOIN [dbo].[Students] AS [Extent2] ON [Extent1].[Student_Id] = [Extent2].[Id]
    LEFT OUTER JOIN [dbo].[Cars] AS [Extent3] ON [Extent1].[Car_Id] = [Extent3].[Id]

又是同样的代码。所以,是的。我们可以说一切都会好起来的,尽管这是件很奇怪的事。

希望这能有所帮助!

票数 5
EN

Stack Overflow用户

发布于 2016-10-26 15:10:59

如果您两次调用它,将生成相同的查询。结果一样,就像这样

代码语言:javascript
复制
SELECT
    [Extent1].[Id] AS [Id],
    [Extent1].[Title] AS [Title],
    [Extent1].[PersonId] AS [PersonId],
    [Extent2].[Id] AS [Id1],
    [Extent2].[Name] AS [Name]
    FROM  [dbo].[Books] AS [Extent1]
    INNER JOIN [dbo].[People] AS [Extent2] ON [Extent1].[PersonId] = [Extent2].[Id]
票数 2
EN

Stack Overflow用户

发布于 2016-10-26 15:18:10

这是完全有效的,不会绊倒EF在任何情况下。考虑一下如何包含附加的引用和集合,这些引用和集合挂起像Student这样的引用。你可以这样写。您提出的建议不会比下面的示例更混淆EF。

代码语言:javascript
复制
.Include(x => x.Student.Teacher)
.Include(x => x.Car)
.Include(x => x.Student.DrivingLog)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40265538

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档