쿼리 작동 방식How Queries Work

Entity Framework Core는 LINQ(Language-Integrated Query)를 사용하여 데이터베이스에서 데이터를 쿼리합니다.Entity Framework Core uses Language Integrated Query (LINQ) to query data from the database. LINQ를 사용하면 C#(원하는 .NET 언어)을 사용하여 파생된 컨텍스트 및 엔터티 클래스를 기반으로 강력한 형식의 쿼리를 작성할 수 있습니다.LINQ allows you to use C# (or your .NET language of choice) to write strongly typed queries based on your derived context and entity classes.

쿼리의 수명The life of a query

각 쿼리를 처리하는 프로세스는 다음과 같이 간략하게 설명할 수 있습니다.The following description is a high-level overview of the process each query goes through.

  1. LINQ 쿼리는 Entity Framework Core에서 처리되어 데이터베이스 공급자가 처리할 수 있는 표현을 작성합니다.The LINQ query is processed by Entity Framework Core to build a representation that is ready to be processed by the database provider
    1. 쿼리가 실행될 때마다 이 처리를 수행할 필요가 없도록 결과가 캐시됩니다.The result is cached so that this processing does not need to be done every time the query is executed
  2. 결과가 데이터베이스 공급자에 전달됩니다.The result is passed to the database provider
    1. 데이터베이스 공급자가 데이터베이스에서 평가할 수 있는 쿼리 부분을 식별합니다.The database provider identifies which parts of the query can be evaluated in the database
    2. 이러한 쿼리 부분이 데이터베이스별 쿼리 언어(예: 관계형 데이터베이스의 경우 SQL)로 변환됩니다.These parts of the query are translated to database-specific query language (for example, SQL for a relational database)
    3. 쿼리가 데이터베이스로 전송되고 결과 집합이 반환됩니다. 결과는 엔터티 인스턴스가 아닌 데이터베이스의 값입니다.A query is sent to the database and the result set returned (results are values from the database, not entity instances)
  3. 결과 집합의 각 항목에 대해 다음을 수행합니다.For each item in the result set
    1. 쿼리가 추적 쿼리인 경우 EF는 데이터가 컨텍스트 인스턴스에 대한 변경 추적 장치에 이미 있는 엔터티를 나타내는지 확인합니다.If the query is a tracking query, EF checks if the data represents an entity already in the change tracker for the context instance
      • 그럴 경우 기존 엔터티가 반환됩니다.If so, the existing entity is returned
      • 그러지 않을 경우 새 엔터티가 만들어지고, 변경 내용 추적이 설정되며, 새 엔터티가 반환됩니다.If not, a new entity is created, change tracking is set up, and the new entity is returned
    2. 쿼리가 비 추적 쿼리인 경우 항상 새 엔터티가 생성되고 반환됩니다.If the query is a no-tracking query, then a new entity is always created and returned

쿼리가 실행되는 경우When queries are executed

LINQ 연산자를 호출할 때는 쿼리의 메모리 내 표현을 작성하기만 하면 됩니다.When you call LINQ operators, you're simply building up an in-memory representation of the query. 쿼리는 결과가 사용될 때만 데이터베이스로 전송됩니다.The query is only sent to the database when the results are consumed.

쿼리를 데이터베이스로 전송하는 가장 일반적인 작업은 다음과 같습니다.The most common operations that result in the query being sent to the database are:

  • for 루프에서 결과 반복Iterating the results in a for loop
  • ToList, ToArray, Single, Count 또는 동등한 비동기 오버로드와 같은 연산자 사용Using an operator such as ToList, ToArray, Single, Count, or the equivalent async overloads

경고

항상 사용자 입력의 유효성 검사: EF Core는 매개 변수를 사용하고 쿼리에서 리터럴을 이스케이프하여 SQL 공격을 방어하지만 입력의 유효성을 검사하지 않습니다.Always validate user input: While EF Core protects against SQL injection attacks by using parameters and escaping literals in queries, it does not validate inputs. 신뢰할 수 없는 소스의 값이 LINQ 쿼리에서 사용되거나, 엔터티 속성에 할당되거나, 다른 EF Core API에 전달되기 전에 애플리케이션의 요구 사항에 따라 적절한 유효성 검사를 수행해야 합니다.Appropriate validation, per the application's requirements, should be performed before values from un-trusted sources are used in LINQ queries, assigned to entity properties, or passed to other EF Core APIs. 여기에는 쿼리를 동적으로 생성하는 데 사용되는 사용자 입력이 포함됩니다.This includes any user input used to dynamically construct queries. LINQ를 사용하는 경우에도 식을 작성하는 사용자 입력을 허용하려면 의도한 식만 생성되도록 해야 합니다.Even when using LINQ, if you are accepting user input to build expressions, you need to make sure that only intended expressions can be constructed.