【问题标题】:How to use LINQs Include in SQL如何使用 LINQ 包含在 SQL 中
【发布时间】:2021-12-11 09:16:58
【问题描述】:

在 LINQ 中,我编写了一个简单的查询,我正在使用 ID 属性搜索动物。但是,我还使用 Include 属性包括了动物所属的农场。

我想在可以包含 Farm 的 SQL 中编写相同的 LINQ 查询。如何使用 SQL 包含 Farm。我在下面有一个不完整的 SQL 语法。谁能帮帮我。

LINQ

await _dbContext.Animals.Where(x => x.id == 1)
                .Include(x => x.Farm)
                .ToListAsync();

SQL

select * from Animals where id = 1;

【问题讨论】:

  • .Include 可能意味着很多东西 - 它可能是 .Join 或其他东西。
  • 我们不知道您的型号,因此无法提供明确的答案。我建议您从 SSMS 运行 SQL Profiler 并附加到您的数据库。它将向您展示 LINQ 生成的 SQL。
  • 我们需要查看样本数据和期望的结果才能知道您的意图。

标签: sql sql-server linq


【解决方案1】:

显然,您的数据库有一个包含 Animals 的表和一个包含 Farms 的表。动物和农场之间似乎存在一对多的关系:在每个农场上生活着零个或多个动物;每个 Animal 都生活在一个 Farm 中,即外键所指的 Farm。

我认为你会有类似于以下的类:

class Farm
{
    public int Id {get; set;}
    public string Name {get; set;}
    ... // etc

    // Every Farm has zero or more Animals (one-to-many)
    public virtual ICollection<Animal> {get; set;}
}

class Animal
{
    public int Id {get; set;}
    public string Name {get; set;}
    ... // etc

    // Every Animal lives on exactly one Farm, using foreign key
    public int FarmId {get; set;}
    public virtual Farm Farm {get; set;}
}

我想在可以包含 Farm 的 SQL 中编写相同的 LINQ 查询。

一个小技巧:如果你想知道Entity Framework生成的SQL代码,使用属性DbContext.Database.Log

using (var dbContext = new DbContext())
{
     // Log generated SQL to debug window:
     dbContext.Database.Log = System.Diagnostics.Debug.Write;

     // execute your LINQ:
     var fetchedAnimals = _dbContext.Animals.Where(x => x.id == 1)
            .Include(x => x.Farm)
            .ToList();
}

编写自己的 SQL

您必须加入 Animals with Farms,并且只保留 ID = 1 的 Animal: 见SQL Join

// Select only the properties of Animals and Farms that you actually plan to use
SELECT Animals.Id, Animals.Name, ...,
       Farms.Id, Farms.Name, ...
FROM Animals INNER JOIN Farms
ON Animals.FarmId = Farm.Id
WHERE Animals.Id = 1

您不应该使用“”来获取所有内容。如果 Farm [10] 有 5000 只鸡,那么每只鸡都会有一个值为 10 的外键。如果你使用“”,你将传递这个值 10 超过 5000 次,而你已经知道外键。

还有改进的余地

使用实体框架获取数据时,始终使用 Select,并且只选择您计划使用的属性,即使您选择所有属性。如果您计划更改/更新获取的数据,请仅省略 Select 和/或使用 Include。

原因是,不使用 Select 获取数据效率不高。

如果你在不使用 Select 的情况下获取数据,实体框架会将获取的项目与获取的项目的副本一起放在 DbContext.ChangeTracker 中。您将获得对副本的引用。每当您更改获取项目的属性时,都会更改 ChangeTracker 中的副本。当你调用DbContext.SaveChanges时,将原始与副本进行比较,每个属性的属性以查看哪些属性发生了更改,因此需要在数据库中进行更新。

因此,如果您不打算更改获取的数据,那么将这些数据和副本放入 ChangeTracker 会浪费处理能力。因此:除非您打算更新获取的数据,否则请始终使用 Select。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-16
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多