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

Comments

  • Anonymous
    May 14, 2009
    PingBack from http://asp-net-hosting.simplynetdev.com/sneak-preview-model-defined-functions/

  • Anonymous
    May 14, 2009
    So would there also be a way to declare it as a property on the entity, so that you could call person.Age rather than Namespace.GetAge(person) and have it translate properly? So for example: from person in ctx.People where person.Age > 35 select person; instead of: from person in ctx.People where Namespace.GetAge(person) > 35 select person; To me that just seems like the intuitive way you would want to work with this from a model/entity standpoint.  It is more readable and O/O, and it would even allow intellisense off of the entity.

  • Anonymous
    May 14, 2009
    I second the motion with shawn!

  • Anonymous
    May 15, 2009
    C#/VS2010 Null is Not Empty VS2010: On Triangles and Performance - It sure looks like the very soon Beta 1 will exhibit some great work on Outlining and Performance Parallel Tasks - new Visual Studio 2010 debugger window ASP.NET Tip #61: Did you know...How

  • Anonymous
    May 15, 2009
    Thank you for submitting this cool story - Trackback from DotNetShoutout

  • Anonymous
    May 15, 2009
    Great to see this information coming out of the ADO.NET team. However, like the fantastic job with ASP.NET MVC would it not be advantageous to release often to get better usage feedback? I personally was disappointed (like many) with v1 and I think a CTP in good faith would be a great idea.  With MVC in full swing I know a lot of people are trying to decide what ORM to go with and if v1 is all they have to work with I doubt ADO.NET EF is going to be their ORM of choice.  I think a CTP would be a great release along with the CTPs of Velocity going around. Just a thought.

  • Anonymous
    May 18, 2009
    @Chad Moran, It would be nice to release more often but as we're part of the .NET Framework we release through those channels.  We look for ways to gather feedback on early design of future features.  Keep your eyes on this blog for more information about new ways we're getting early bits to developers. Carl

  • Anonymous
    June 03, 2009
    As an excessively picky English speaker as well as a programmer, I'd like to request that these be renamed Model-Defined Functions, with a hyphen joining the compound adjective.

  • Anonymous
    July 19, 2009
    C#/VS2010 Null is Not Empty VS2010: On Triangles and Performance - It sure looks like the very soon Beta 1 will exhibit some great work on Outlining and Performance Parallel Tasks - new Visual Studio 2010 debugger window ASP.NET Tip #61: Did you know...How