How to: Call model-defined functions in queries

This topic describes how to call functions that are defined in the conceptual model from within LINQ to Entities queries.

The procedure below provides a high-level outline for calling a model-defined function from within a LINQ to Entities query. The example that follows provides more detail about the steps in the procedure. The procedure assumes that you have defined a function in the conceptual model. For more information, see How to: Define Custom Functions in the Conceptual Model.

To call a function defined in the conceptual model

  1. Add a common language runtime (CLR) method to your application that maps to the function defined in the conceptual model. To map the method, you must apply an EdmFunctionAttribute to the method. Note that the NamespaceName and FunctionName parameters of the attribute are the namespace name of the conceptual model and the function name in the conceptual model respectively. Function name resolution for LINQ is case sensitive.

  2. Call the function in a LINQ to Entities query.

Example 1

The following example demonstrates how to call a function that is defined in the conceptual model from within a LINQ to Entities query. The example uses the School model. For information about the School model, see Creating the School Sample Database and Generating the School .edmx File.

The following conceptual model function returns the number of years since an instructor was hired. For information about adding the function to a conceptual model, see How to: Define Custom Functions in the Conceptual Model.

<Function Name="YearsSince" ReturnType="Edm.Int32">
  <Parameter Name="date" Type="Edm.DateTime" />
  <DefiningExpression>
    Year(CurrentDateTime()) - Year(date)
  </DefiningExpression>
</Function>

Example 2

Next, add the following method to your application and use an EdmFunctionAttribute to map it to the conceptual model function:

[EdmFunction("SchoolModel", "YearsSince")]
public static int YearsSince(DateTime date)
{
    throw new NotSupportedException("Direct calls are not supported.");
}
<EdmFunction("SchoolModel", "YearsSince")>
Public Function YearsSince(ByVal date1 As DateTime) _
    As Integer
    Throw New NotSupportedException("Direct calls are not supported.")
End Function

Example 3

Now you can call the conceptual model function from within a LINQ to Entities query. The following code calls the method to display all instructors that were hired more than ten years ago:

using (SchoolEntities context = new SchoolEntities())
{
    // Retrieve instructors hired more than 10 years ago.
    var instructors = from p in context.People
                      where YearsSince((DateTime)p.HireDate) > 10
                      select p;

    foreach (var instructor in instructors)
    {
        Console.WriteLine(instructor.LastName);
    }
}
Using context As New SchoolEntities()
    ' Retrieve instructors hired more than 10 years ago.
    Dim instructors = From p In context.People _
                      Where YearsSince(CType(p.HireDate, DateTime?)) > 10 _
                      Select p

    For Each instructor In instructors
        Console.WriteLine(instructor.LastName)
    Next
End Using

See also