11
votes

Does anyone know if it is possible to use TVFs in the entity framework using code-first? To be specific:

I know this is not supported for code-first currently (and it does not look like EF6 will allow it either). On the other hand, later versions of EF support TVFs in a database-first scenario (which is not an option for me). I am wondering if anyone know if there is some way to emulate what database first does by manipulating the model or something similar?

One further clarification; I know its possible to include TVFs by using SQL, but I also need the TVFs to be composable (i.e. be part of the entity LINQ statement).

3
In EF6, a very hacky workaround is to use an interceptor to rewrite an entity's table name to be a TVF call. I've made an example implementation here. Not recommended!sinelaw
This is now possible with EF6.1 and the custom convention I created. Take a look at my answer below.Pawel

3 Answers

8
votes

This is now possible. I created a custom model convention which allows using store functions in CodeFirst in EF6.1. The convention is available on NuGet http://www.nuget.org/packages/EntityFramework.CodeFirstStoreFunctions. Here is the link to the blogpost containing all the details: http://blog.3d-logic.com/2014/04/09/support-for-store-functions-tvfs-and-stored-procs-in-entity-framework-6-1/

1
votes

It is not currently possible. It was postponed until after EF6. The best thing to do is vote for it on their User Voice board. The feature suggestion is titled "Code First support for Table-Valued Functions". I just put in 3 votes for it.

-3
votes

You can use Table-Valued Function in Entity Framework 5.I think the link will solve your question:

For using Table Value Function in Entity Framework you need to do the following steps:

1. Right-click the project name in Solution Explorer, point to Add, and then click New
Item.

2. Select Data from the left menu and then select ADO.NET Entity Data Model in the Templates pane.

3. Enter TVFModel.edmx for the file name, and then click Add.

4. In the Choose Model Contents dialog box, select Generate from database, and then click Next.

5. Click New Connection Enter (localdb)\v11.0 in the Server name text box Enter School for the database name Click OK.

6. In the Choose Your Database Objects dialog box, under the Tables node, select the
Person, StudentGrade, and Course tables.

7. Select the GetStudentGradesForCourse function located under the Stored Procedures and Functions node Note, that starting with Visual Studio 2012, the Entity Designer
allows you to batch import your Stored Procedures and Functions.

8. Click Finish.

9. The Entity Designer, which provides a design surface for editing your model, is
displayed. All the objects that you selected in the Choose Your Database Objects
dialog box are added to the model.

10. By default, the result shape of each imported stored procedure or function will
automatically become a new complex type in your entity model. But we want to map the results of the GetStudentGradesForCourse function to the StudentGrade entity: Right-click the design surface and select Model Browser In Model Browser, select Function Imports, and then double-click the
GetStudentGradesForCourse function In the Edit Function Import dialog box, select Entities and choose StudentGrade

You can use the following code to use Table-Value Function in the Application for retrieving data:

using (var context = new SchoolEntities())
{
    var CourseID = 4022;
    var Grade = 3.5M;

    // Return all the best students in the Microeconomics class.
    var students = from s in context.GetStudentGradesForCourse(CourseID)
                            where s.Grade >= Grade
                            select new
                            {
                                s.Person,
                                s.Course.Title
                            };

    foreach (var result in students)
    {
        Console.WriteLine(
            "Couse: {0}, Student: {1} {2}",
            result.Title, 
            result.Person.FirstName, 
            result.Person.LastName);
    }
}