diff --git a/entity-framework/core/querying/database-functions.md b/entity-framework/core/querying/database-functions.md new file mode 100644 index 0000000000..14a79dfe86 --- /dev/null +++ b/entity-framework/core/querying/database-functions.md @@ -0,0 +1,55 @@ +--- +title: Database Functions - EF Core +description: Information on database functions supported in EF Core query translation +author: smitpatel +ms.date: 11/10/2020 +uid: core/querying/database-functions +--- +# Database Functions + +Database functions are database equivalent of [C# methods](/dotnet/csharp/programming-guide/classes-and-structs/methods). A database function can be invoked with zero or more parameters and it computes the result based on the parameter values. Most databases, which use SQL for query have support for database functions. So SQL generated by EF Core query translation also allows invoking database functions. C# methods don't have to translate to database functions strictly in EF Core. + +- A C# method may not have an equivalent database function. + - method translates to a null check and a comparison with an empty string in the database rather than a function. + - method doesn't have database equivalent since string comparison can't be represented or mimicked easily in a database. +- A database function may not have an equivalent C# method. `??` operator in C#, which doesn't have any method, translates to `COALESCE` function in database. + +## Types of database functions + +EF Core SQL generation supports a subset of functions that can be used in database. This limitation comes from the ability to represent query in LINQ for the given database function. Further, each database has varying support of database functions, so EF Core provides a common subset. A database provider is free to extend EF Core SQL generation to support more patterns. Following are type of the database functions EF Core supports and uniquely identifies. These terms also help in understanding what translations come built in with EF Core provider. + +### Built-in vs user-defined functions + +Built-in functions come with database predefined, but user-defined functions are explicitly defined by the user in the database. When EF Core translates query to use database functions, it uses built-in functions to make sure that the function is always available on database. The distinction of built-in function is necessary in some databases to generate SQL correctly. For example SqlServer requires that every user-defined function is invoked with schema qualified name. But built-in functions in SqlServer don't have any schema. PostgreSQL defines built-in function in `public` schema and it can be invoked with schema qualified name. + +### Aggregate vs scalar vs table-valued functions + +- Scalar functions take scalar values as parameter(s) and return a scalar value as the result. Scalar functions can be used anywhere in SQL where a scalar value can be passed. +- Aggregate functions take a stream of scalar values as parameter and return a scalar value as the result. Aggregate functions are applied on whole query result set or on group of values generated by applying `GROUP BY` operator. +- Table-valued functions take scalar values as parameter(s) and return a stream of rows as the result. Table-valued functions are used as a table source in `FROM` clause. + +### Niladic functions + +Niladic functions are special database functions that don't have any parameters and must be invoked without parenthesis. They're similar to property/field access on an instance in C#. Niladic functions differ from parameter-less functions as the latter require empty parenthesis. There's no special name for database functions that requires parenthesis always. Another subset of database functions based on parameter count is variadic functions. Variadic functions can take varying number of parameters when invoked. + +## Database function mappings in EF Core + +EF Core supports three different kinds of mapping between C# functions and database functions. + +### Built-in function mapping + +By default EF Core providers provide mappings for various built-in functions over primitive types. For example, translates to `LOWER` in SqlServer. This functionality allows users to write query in LINQ seamlessly. We usually provide translation in the database, which gives same result as what C# function provides on client side. Sometimes, to achieve that, the actual translation could be something more complicated then a database function. In some scenarios, we also provide the most appropriate translation rather than matching C# semantics. The same feature is also used to provide common translations for some of the C# member accesses. For example, translates to `LEN` in SqlServer. Apart from providers, plugin writers can also add additional translations. This extensibility is useful when plugins add support for more types as primitive types and want to translate methods over them. + +### EF.Functions mapping + +Since not all database functions have C# equivalent functions, EF Core providers have special C# methods to invoke certain database functions. These methods are defined as extension methods over `EF.Functions` to be used in LINQ queries. These methods are provider-specific as they're closely tied with particular database functions. So a method that works for one provider will likely not work for any other provider. Further, since the intention of these methods to invoke database function in translated query, trying to evaluate them on client-side results in an exception. + +### User-defined function mapping + +Apart from mappings provided by EF Core providers, users can also define custom mapping. User-defined mapping extends query translation according to user needs. This functionality is useful when there are user-defined functions in the database which user wants to invoke from their LINQ query. + +## See also + +- [SqlServer built-in Function Mappings](xref:core/providers/sql-server/functions) +- [Sqlite built-in Function Mappings](xref:core/providers/sqlite/functions) +- [Cosmos built-in Function Mappings](xref:core/providers/cosmos/functions) diff --git a/entity-framework/toc.yml b/entity-framework/toc.yml index 5a1c927f82..bfc58b31cc 100644 --- a/entity-framework/toc.yml +++ b/entity-framework/toc.yml @@ -163,6 +163,10 @@ items: - name: Overview href: core/querying/index.md + - name: Client vs. server evaluation + href: core/querying/client-eval.md + - name: Tracking vs. no-tracking + href: core/querying/tracking.md - name: Load related data items: - name: Overview @@ -175,16 +179,16 @@ href: core/querying/related-data/lazy.md - name: Related data and serialization href: core/querying/related-data/serialization.md - - name: Client vs. server evaluation - href: core/querying/client-eval.md - - name: Tracking vs. no-tracking - href: core/querying/tracking.md - name: Split queries href: core/querying/single-split-queries.md - name: Complex query operators href: core/querying/complex-query-operators.md - name: Raw SQL queries href: core/querying/raw-sql.md + - name: Database functions + href: core/querying/database-functions.md + #- name: User defined functions + # href: core/querying/user-defined-functions.md - name: Global query filters href: core/querying/filters.md - name: Query tags