Sneak Preview: Model Defined Functions

 


The information in this post is out of date.

Visit msdn.com/data/ef for the latest information on current and past releases of EF.


 

Model Defined Functions is a new feature coming in .NET 4.0. They are similar to SqlServer Table Value Functions because they are composable, so you can layer function calls and queries. The key difference is that they are declared in terms of the conceptual model, rather than the storage model so they are defined in eSQL not T-SQL.

Model Defined Functions are useful if you want to encapsulate some commonly used eSQL in a function, for example something that calculates a person’s age.

To create a function that does that all you do is add something like this to the CSDL under the Schema element.

 <Function Name="GetAge" ReturnType="Edm.Int32">
     <Parameter Name="Person" Type="Model.Person" />
     <DefiningExpression>
           Edm.DiffYears(Edm.CurrentDateTime(), Person.Birthday)
     </DefiningExpression>
</Function>

Notice that the DefiningExpression can be any valid eSQL expression that matches the expected ReturnType. Parameters, like Person, are referenced directly in the eSQL by name, without an @ symbol.

With this definition in place you can use it in eSQL queries immediately like this:

 SELECT VALUE(P) FROM [MyEntityContainer].[People] 
AS P WHERE Namespace.GetAge(P) > 35 

If you want to use the function in LINQ you need to have a corresponding CLR method that you can call. Essentially this is just a method stub too, something that has the same type signature, i.e. a function that takes a Person and returns an int.

 [

EdmFunction

 ("Namespace", "GetAge")]
public int GetAge(

Person

  p)
{ 
    throw new 

NotSupportedException

 (…);
}

Here the EdmFunction attribute allows the Entity Framework to map calls to this function in a LINQ expression back to the Model Defined Function.

With this in place the Entity Framework can translate the LINQ query below into something that can run completely in the database.

 var results = from person in ctx.People
              where GetAge(person) > 35
              select person;

This simple example barely scratches the surface of the sorts of things you can do with Model Defined Functions.

Look out for a more in depth post on Model Defined Functions soon.

- Alex James
Program Manager, Entity Framework