全域查詢篩選條件Global Query Filters

全域查詢篩選條件是中繼資料模型 (通常位於 OnModelCreating) 中套用到實體類型的 LINQ 查詢述詞 (布林運算式通常會傳遞到 LINQ Where 查詢運算子)。Global query filters are LINQ query predicates (a boolean expression typically passed to the LINQ Where query operator) applied to Entity Types in the metadata model (usually in OnModelCreating). 這類篩選會自動套用至任何涉及這些「實體類型」(包含間接參考的「實體類型」) 的 LINQ 查詢 (例如,使用 Include 或直接導覽屬性參考)。Such filters are automatically applied to any LINQ queries involving those Entity Types, including Entity Types referenced indirectly, such as through the use of Include or direct navigation property references. 此功能的一些常見應用如下:Some common applications of this feature are:

  • 虛刪除:實體類型會定義 IsDeleted 屬性。Soft delete - An Entity Type defines an IsDeleted property.
  • 多租用戶:實體類型會定義 TenantId 屬性。Multi-tenancy - An Entity Type defines a TenantId property.

範例Example

下列範例示範如何使用全域查詢篩選條件,在簡單的部落格模型中實作虛刪除和多租用戶查詢行為。The following example shows how to use Global Query Filters to implement soft-delete and multi-tenancy query behaviors in a simple blogging model.

提示

您可以在 GitHub 上檢視此文章的範例 (英文)。You can view this article's sample on GitHub.

首先,定義實體:First, define the entities:

[!code-csharp[Main](../../../efcore-dev/samples/QueryFilters/Program.cs#Entities)]

請注意 Blog 實體上 _tenantId 欄位的宣告。Note the declaration of a _tenantId field on the Blog entity. 這會用來將每個 Blog 執行個體與特定租用戶產生關聯。This will be used to associate each Blog instance with a specific tenant. 此外,還定義了 Post 實體類型上的 IsDeleted 屬性。Also defined is an IsDeleted property on the Post entity type. 這會用來追蹤是否已將 Post 執行個體「虛刪除」。This is used this to keep track of whether a Post instance has been "soft-deleted". 也就是,將執行個體標示為已刪除,而不需實際移除基礎資料。I.e. The instance is marked as deleted withouth physically removing the underlying data.

接下來,使用 HasQueryFilter API,在 OnModelCreating 中設定查詢篩選條件。Next, configure the query filters in OnModelCreating using the HasQueryFilter API.

[!code-csharp[Main](../../../efcore-dev/samples/QueryFilters/Program.cs#Configuration)]

傳遞到 HasQueryFilter 呼叫的述詞運算式,現在將針對那些類型自動套用到任何 LINQ 查詢。The predicate expressions passed to the HasQueryFilter calls will now automatically be applied to any LINQ queries for those types.

提示

請注意 DbContext 執行個體層級欄位的使用方式:_tenantId 用來設定目前的租用戶。Note the use of a DbContext instance level field: _tenantId used to set the current tenant. 模型層級篩選將使用正確內容執行個體中的值。Model-level filters will use the value from the correct context instance. 也就是,執行查詢的執行個體。I.e. The instance that is executing the query.

停用篩選條件Disabling Filters

可能會使用 IgnoreQueryFilters() 運算子來停用個別 LINQ 查詢的篩選條件。Filters may be disabled for individual LINQ queries by using the IgnoreQueryFilters() operator.

[!code-csharp[Main](../../../efcore-dev/samples/QueryFilters/Program.cs#IgnoreFilters)]

限制Limitations

全域查詢篩選條件具有下列限制:Global query filters have the following limitations:

  • 篩選條件不能包含對導覽屬性的參考。Filters cannot contain references to navigation properties.
  • 只能針對繼承階層的根實體類型定義篩選條件。Filters can only be defined for the root Entity Type of an inheritance hierarchy.