Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Core Database Table Valued Functions Mapping

I use EFCore 2.1 Database First approach. I'm pretty familiar with SQL syntax and prefer build queries myself rather then leave this work on EF. I use Table Valued and Scalar Functions for querying the database.

I found this for Scalar

https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#database-scalar-function-mapping

But unfortunately nothing about Table Functions.

Is there any way to force Visual Studio grab all Table Functions and Scalar Functions and Stored Procedures from SQL Server, when I run Scaffolding?

I was using LINQ to SQL dbml designer before. Everything was extremely simple with dbml. You drag from Server Explorer drop to dbml and boom, I can use SQL Function or SP like regular C# method.

enter image description here

Any chance to reproduce this in EFCore?

like image 651
Michael Samteladze Avatar asked Sep 11 '18 13:09

Michael Samteladze


People also ask

How to use EF Core Functions in LINQ queries?

Once we define the function, it can be used in the query. Instead of calling database function, EF Core will translate the method body directly into SQL based on the SQL expression tree constructed from the HasTranslation. The following LINQ query: SELECT 100 * (ABS(CAST( [p]. [BlogId] AS float) - 3) / ( (CAST( [p].

What is TVF in Entity Framework 5?

Entity Framework 5 brings number of improvements and Mapping Table-Valued Functions (TVFs) Support is one of them. Entity Framework 5 brings many improvements and one of them is Mapping Table-Valued Functions (TVFs) Support.

How does EF Core translate method body to SQL?

Instead of calling database function, EF Core will translate the method body directly into SQL based on the SQL expression tree constructed from the HasTranslation. The following LINQ query: SELECT 100 * (ABS(CAST( [p]. [BlogId] AS float) - 3) / ( (CAST( [p]. [BlogId] AS float) + 3) / 2)) FROM [Posts] AS [p]

How do I add a database in Entity Framework?

So, to use this database in EF, we need to add an ADO.NET Entity Data Model. Right-click the project name in Solution Explorer, point to Add, and then click New Item. Select Data from the left menu and then select ADO.NET Entity Data Model in the Templates pane. Enter Model1.edmx for the file name, and then click Add.


2 Answers

There's no reverse engineer (aka DbContext scaffolding) support for it, but you can use FromSql() to query using table-valued functions. See these docs.

var searchTerm = "EF Core";
var blogResults = db.Blogs.FromSql(
    "SELECT * FROM dbo.SearchBlogs({0})",
    searchTerm);
like image 51
bricelam Avatar answered Sep 21 '22 12:09

bricelam


Source : https://www.allhandsontech.com/data-professional/entityframework/entity-framework-core-advanced-mapping/

Use HasDbFunction to do a mapping, refer Microsoft doc

It requires return types to be declared as Keyless entity using HasNoKeyMicrosoft doc

Configure EF Context to expose Db function

modelBuilder.HasDbFunction(typeof(SalesContext)
    .GetMethod(nameof(NameAndTotalSpentByCustomer)))
    .HasName("CustomerNameAndTotalSpent");

modelBuilder.Entity<CustWithTotalClass>().HasNoKey();

Invoke Db function in calling code

_context.NameAndTotalSpentByCustomer().Where(c=>c.TotalSpent>100).ToList();

Generated SQL

SELECT [c].[Name], [c].[TotalSpent]
FROM [dbo].[CustomerNameAndTotalSpent]() AS [c]
WHERE [c].[TotalSpent] > 100
like image 31
Maulik Modi Avatar answered Sep 23 '22 12:09

Maulik Modi