<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Entity Framework Design : Linq to Entities</title><link>http://blogs.msdn.com/efdesign/archive/tags/Linq+to+Entities/default.aspx</link><description>Tags: Linq to Entities</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Model Defined Functions</title><link>http://blogs.msdn.com/efdesign/archive/2009/01/07/model-defined-functions.aspx</link><pubDate>Wed, 07 Jan 2009 23:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9290047</guid><dc:creator>efdesign</dc:creator><slash:comments>21</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/9290047.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=9290047</wfw:commentRss><description>&lt;P&gt;Today the Entity Framework, and more specifically the Entity Data Model, have a limited notion of Functions.&lt;/P&gt;
&lt;P&gt;We are currently restricted to Function Imports that allow stored procedures to be invoked, and Canonical / Store Functions for database independent and database specific functions respectively.&lt;/P&gt;
&lt;P&gt;Now however we want to &lt;SPAN style="mso-fareast-language: ja"&gt;support functions defined, not just declared, in the EDM (&lt;A href="http://blogs.msdn.com/alexj/archive/2008/11/24/edm-misconceptions.aspx" mce_href="http://blogs.msdn.com/alexj/archive/2008/11/24/edm-misconceptions.aspx"&gt;aka. the CSDL&lt;/A&gt;). &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="mso-fareast-language: ja"&gt;An example would be: &lt;/SPAN&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none; mso-outline-level: 1" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: #a31515; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;Function&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: red; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;"&lt;SPAN style="COLOR: blue"&gt;GetAge&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ReturnType&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Edm.Int32&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: #a31515; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;Parameter&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: red; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;"&lt;SPAN style="COLOR: blue"&gt;Person&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Model.Person&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: #a31515; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;DefiningExpression&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&amp;gt;&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;FONT color=#000000&gt;Edm.DiffYears(Edm.CurrentDateTime(), Person.Birthday)&lt;/FONT&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: #a31515; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;DefiningExpression&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: ; COLOR: #a31515; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;Function&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&amp;gt; &lt;/SPAN&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="mso-no-proof: yes"&gt;Here are some things to notice:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;The DefiningExpression is eSQL.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;The function can have zero or more parameters.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;The Function must have a return type.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;Function Parameters are referenced directly by Name in the DefiningExpression: meaning there is no parameter denoting prefix like @. This means you must be careful to choose parameter names that don't collide with identifiers you need to use in the rest of eSQL expression.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;Unlike functions in SSDL, functions in CSDL only support In bound Parameters (i.e &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Mode&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt;") &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes; mso-bidi-font-family: 'Courier New'; mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;because otherwise they become non-composable.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes; mso-bidi-font-family: 'Courier New'; mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes; mso-bidi-font-family: 'Courier New'; mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;For this reason the &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Mode&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes; mso-bidi-font-family: 'Courier New'; mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;of a parameter cannot be set in CSDL (it is always &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Mode&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;In&lt;/SPAN&gt;"&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes; mso-bidi-font-family: 'Courier New'; mso-ascii-font-family: calibri; mso-hansi-font-family: calibri; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin"&gt;).&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;Functions are declared as Global Items and are declared&amp;nbsp;within the &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Schema&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;element. As such there identity is made up of the Schema's namespace and the function name.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;The function parameters and return type can be any of the following:&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;A scalar type or collection of scalar types.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;An entity type or collection of entity types.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;A complex type or collection of complex types.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;A row type or collection of row types (See below).&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;A ref type or collection of ref types.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;SPAN style="mso-no-proof: yes"&gt;Functions with a DefiningExpression do not require mapping, since the eSQL expression is composed out of eSQL fragments that are already mapped.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&lt;SPAN style="mso-no-proof: yes"&gt;Functions without a DefiningExpression are simply declarations. Today the Entity Framework doesn't complain when loading a CSDL with such a function, but you can't invoke it. In the future these functions might be used to support mapping Table Value Functions in the store to functions in the Conceptual Model.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN&gt;&lt;SPAN&gt;Since it is trivial in eSQL to create arbitrary un-named types, imagine a projection that projects 3 of the properties from an Entity, we now need a mechanism for defining these "RowTypes" inline, so that they can be used when defining Function Parameters and ReturnTypes. For example:&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes; mso-fareast-language: ja"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes; mso-fareast-language: ja"&gt;Parameter&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;Coordinate&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;RowType&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;gt; &lt;BR&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Property&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;X&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Nullable&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt; &lt;BR&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Property&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Y&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Nullable&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt; &lt;BR&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Property&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Z&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Nullable&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;RowType&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Parameter&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;&lt;SPAN&gt;&lt;SPAN&gt;Since eSQL is primarily set based, we also need a way of defining parameters and return types that are collections of RowTypes: &lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes; mso-fareast-language: ja"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes; mso-fareast-language: ja"&gt;Parameter&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;Coordinates&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;CollectionType&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;RowType&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;gt; &lt;BR&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Property&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: red; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;=&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;"&lt;SPAN style="COLOR: blue"&gt;X&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Nullable&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt; &lt;BR&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Property&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Y&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Nullable&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt; &lt;BR&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Property&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Z&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Nullable&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;RowType&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt; &lt;BR&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;CollectionType&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;gt;&lt;/SPAN&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;Parameter&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Using the Function via eSQL:&lt;/H3&gt;
&lt;P&gt;It is trivial to use the function via eSQL. For example:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: #17365d" new?;="new?;" courier="courier" mso-themecolor:="mso-themecolor:" mso-themeshade:="mso-themeshade:" 191?="191?" text2;="text2;" JA;="JA;" mso-fareast-language:="mso-fareast-language:"&gt;SELECT&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: " new?;="new?;" courier="courier" mso-fareast-language:="mso-fareast-language:" JA?="JA?"&gt; Namespace.GetAge(p) &lt;BR&gt;&lt;SPAN style="COLOR: #17365d; mso-themecolor: text2; mso-themeshade: 191"&gt;FROM&lt;/SPAN&gt; Container.People &lt;SPAN style="COLOR: #17365d; mso-themecolor: text2; mso-themeshade: 191"&gt;AS&lt;/SPAN&gt; P &lt;BR&gt;&lt;SPAN style="COLOR: #17365d; mso-themecolor: text2; mso-themeshade: 191"&gt;WHERE&lt;/SPAN&gt; P.Firstname = &lt;SPAN style="COLOR: red"&gt;‘Jim’ &lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;P&gt;Here we get Jim's age, assuming of course there is only one Jim!&lt;/P&gt;
&lt;P&gt;It is also possible to compose functions together, you must simply ensure return types and target parameter types are the same (in the case of named types) or structurally equivalent (in the case of row types or collections of row types).&lt;/P&gt;
&lt;P&gt;Things get a little trickier when you are dealing with functions that return sets, for example imagine a function that returns someone's friends, used in conjunction with the GetAge function:&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: #1f497d" new?;="new?;" courier="courier" mso-themecolor:="mso-themecolor:" text2?="text2?"&gt;SELECT&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: " courier="courier" new??="new??"&gt; &lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;VALUE&lt;/SPAN&gt; (F) &lt;BR&gt;&lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;FROM&lt;/SPAN&gt; Container.People &lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;AS&lt;/SPAN&gt; P &lt;BR&gt;&lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;CROSS&lt;/SPAN&gt; &lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;APPLY&lt;/SPAN&gt; Namespace.GetFriends(P) &lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;AS&lt;/SPAN&gt; F &lt;BR&gt;&lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;WHERE&lt;/SPAN&gt; Namespace.GetAge(P) &amp;gt; 21 &lt;/SPAN&gt;
&lt;P&gt;Here we get all the friends of people older than 21.&lt;/P&gt;
&lt;P&gt;As you can see to do this sort of thing you need a crash course in eSQL. &lt;/P&gt;
&lt;H3&gt;Using the Function via LINQ:&lt;/H3&gt;
&lt;P&gt;It is also possible to use these functions in LINQ, but this does require a extra step to create an appropriate stub function in the CLR.&lt;/P&gt;
&lt;P&gt;This solution is based on the techniques described &lt;A href="http://blogs.msdn.com/efdesign/archive/2008/10/08/edm-and-store-functions-exposed-in-linq.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/10/08/edm-and-store-functions-exposed-in-linq.aspx"&gt;here&lt;/A&gt;, and involves creating a Stub function in the CLR language of your choice, and annotating it something like this:&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN-BOTTOM: 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;[&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: #2b91af"&gt;EdmFunction&lt;/SPAN&gt;&lt;/SPAN&gt;(&lt;FONT color=#ff0000&gt;"Namespace"&lt;/FONT&gt;, &lt;FONT color=#ff0000&gt;"GetAge"&lt;/FONT&gt;)] &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt; &lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;static &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int &lt;/SPAN&gt;GetAge(&lt;SPAN style="COLOR: #2b91af"&gt;Person&lt;/SPAN&gt; p) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;{&amp;nbsp; &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #31849b; mso-themecolor: accent5; mso-themeshade: 191"&gt;NotSupportedException&lt;/SPAN&gt;&lt;SPAN style="COLOR: #1f497d; mso-themecolor: text2"&gt;(…); &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;}&lt;/SPAN&gt;&lt;SPAN style="mso-fareast-language: ja"&gt; &lt;/SPAN&gt;
&lt;P&gt;The Entity Framework uses the signature of the function and the EdmFunction attribute to map calls to this function when encountered to the appropriate Model Defined Function.&lt;/P&gt;
&lt;P&gt;Once you have this stub it is then trivial to use it in a LINQ query like this:&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: ; COLOR: blue; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;var&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt; peopleOver21 = &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from&lt;/SPAN&gt; p &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ctx&lt;/SPAN&gt;.People &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where&lt;/SPAN&gt; GetAge(p) &amp;lt; 21 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: ; FONT-SIZE: 10pt" new?;="new?;" courier="courier" yes?="yes?" mso-no-proof:="mso-no-proof:"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select&lt;/SPAN&gt; p; &lt;/SPAN&gt;
&lt;P&gt;Indeed if you are familiar with LINQ you will probably find composing functions together a lot easier too:&lt;/P&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;var&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt; friendOfPeopleOver21 = &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from&lt;/SPAN&gt; p &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ctx&lt;/SPAN&gt;.People &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt;&amp;nbsp;&lt;FONT color=#000000&gt;f&lt;/FONT&gt; &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt;&amp;nbsp;&lt;FONT color=#000000&gt;GetFriends(p)&lt;/FONT&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where&lt;/SPAN&gt; GetAge(p) &amp;lt; 21 &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select&lt;/SPAN&gt; f; 
&lt;P mce_keep="true"&gt;&lt;/SPAN&gt;Notice that the CLR functions don't need to be directly callable, in the example above the CLR stub throws an exception if called directly. &lt;/P&gt;
&lt;P&gt;However the existence of the stub allows you to create LINQ expressions that compile correctly, and then at runtime, when used in a LINQ to Entities query, the function call is simply translated by the entity framework into a query that runs in the database.&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P&gt;As you can see Model Defined Function's are very powerful, and this post has barely scratched the surface of possibilities they open up.&lt;/P&gt;
&lt;P&gt;The Entity Framework team would love to hear your comments.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;Alex James&lt;/A&gt;&lt;/STRONG&gt;&amp;nbsp; &lt;BR&gt;Program Manager, &lt;BR&gt;Entity Framework Team&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at &lt;A href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx"&gt;this post&lt;/A&gt;.&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9290047" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/EDM/default.aspx">EDM</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Linq+to+Entities/default.aspx">Linq to Entities</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Functions/default.aspx">Functions</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/eSQL/default.aspx">eSQL</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+4/default.aspx">Entity Framework 4</category></item><item><title>EDM and Store functions exposed in LINQ</title><link>http://blogs.msdn.com/efdesign/archive/2008/10/08/edm-and-store-functions-exposed-in-linq.aspx</link><pubDate>Wed, 08 Oct 2008 11:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8962709</guid><dc:creator>efdesign</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/efdesign/comments/8962709.aspx</comments><wfw:commentRss>http://blogs.msdn.com/efdesign/commentrss.aspx?PostID=8962709</wfw:commentRss><description>&lt;p&gt;In this post &lt;a href="http://blogs.msdn.com/meek" mce_href="http://blogs.msdn.com/meek"&gt;Colin Meek&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/diego" mce_href="http://blogs.msdn.com/diego"&gt;Diego Vega&lt;/a&gt; delve into some enhancements we are planning for LINQ to Entities, anyway over to them... &lt;/p&gt;  &lt;p&gt;Entity Framework v1 customers preferring to write their queries using LINQ often hit a limitation on the range of functions and query patterns supported in LINQ to Entities. For some of those customers, having to resort to Entity SQL, or even to Entity SQL builder methods, feels awkward and reduces the appeal of Entity Framework. &lt;/p&gt;  &lt;p&gt;There are two things we want to do in order to address this in future versions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;Expand the range of patterns and standard BCL methods we recognize in LINQ expressions.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Provide an extensibility mechanism that people can use to map arbitrary CLR methods to appropriate server and EDM functions. &lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This blog post expands on the second approach: &lt;/p&gt;  &lt;p&gt;It is actually possible for us to improve our LINQ implementation so that all functions defined in the EDM and in the store, and even user defined functions, can be mapped to CLR methods with homologous signatures.&lt;/p&gt;  &lt;h3&gt;Design&lt;/h3&gt;  &lt;h4&gt;Problem space&lt;/h4&gt;  &lt;p&gt;There are multiple dimensions to the problem space we want to address:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;Functions can be defined in either the conceptual or the storage space&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Functions can be defined in either the manifest, or just declared in the model&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Functions can be mapped to either static CLR methods or to instance methods on the ObjectContext&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;This feature specifically targets composable functions &lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;How it looks like: EdmFunctionAttribute &lt;/h4&gt;  &lt;p&gt;The basis of the extensibility mechanism is a new method-level attribute that carry function mapping information. Here is the basic signature of the attribute’s constructor: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;public &lt;/span&gt;EdmFunctionAttribute(&lt;span class="keyword"&gt;string &lt;/span&gt;namespaceName, &lt;span class="keyword"&gt;string &lt;/span&gt;functionName) &lt;/div&gt;  &lt;p&gt;The namespaceName parameter indicates the namespace for the function in metadata (i.e. “EDM” or “SQLSERVER”, or other store provider namespace). The functionName parameter takes the name of the function itself.&lt;/p&gt;  &lt;p&gt;The following example could be product code or customer code applying the attribute on an extension method (it could be a regular static function) in order to map it to the standard deviation SQL Server function:&lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public static class &lt;/span&gt;&lt;span class="type"&gt;SqlFunctions &lt;/span&gt;      &lt;br&gt;{       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"SqlServer"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"stdev"&lt;/span&gt;)]       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public static double?&lt;/span&gt; StandardDeviation(&lt;span class="keyword"&gt;this &lt;/span&gt;IEnumerable&amp;lt;&lt;span class="keyword"&gt;int?&lt;/span&gt;&amp;gt; source)       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/span&gt;    &lt;br&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw &lt;/span&gt;EntityUtil.NotSupported(       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Data.Entity.Strings.ELinq_EdmFunctionDirectCall);       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }       &lt;br&gt;} &lt;/span&gt;&lt;/div&gt;  &lt;p&gt;Notice that while this method can’t be called directly it can be used in a query like this: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span&gt;&lt;span class="keyword"&gt;var &lt;/span&gt;query =&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;from&lt;/span&gt; p &lt;span class="keyword"&gt;in &lt;/span&gt;context.Products       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;where &lt;/span&gt;!p.Discontinued       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;group &lt;/span&gt;p &lt;span class="keyword"&gt;by &lt;/span&gt;p.Category &lt;span class="keyword"&gt;into &lt;/span&gt;g       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;select &lt;/span&gt;g.Select(each =&amp;gt; each.ReorderLevel).StandardDeviation(); &lt;/span&gt;&lt;/div&gt;  &lt;p&gt;The following example shows how the canonical DiffYear function is mapped: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; &lt;span class="type"&gt;EntityFunctions        &lt;br&gt;&lt;/span&gt;{       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"EDM"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"DiffYears"&lt;/span&gt;)]       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;Int32&lt;/span&gt;? DiffYears(&lt;span class="type"&gt;DateTime&lt;/span&gt;? arg1, &lt;span class="type"&gt;DateTime&lt;/span&gt;? arg2)       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {       &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;throw&lt;/span&gt; EntityUtil.NotSupported(System.Data.Entity.Strings.ELinq_EdmFunctionDirectCall);&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }       &lt;br&gt;} &lt;/span&gt;&lt;/div&gt;  &lt;p&gt;Usage is: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;var &lt;/span&gt;query =     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;from &lt;/span&gt;p &lt;span class="keyword"&gt;in &lt;/span&gt;context.Products     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;where &lt;/span&gt;&lt;span class="type"&gt;EntityFunctions&lt;/span&gt;.DiffYears(DateTime.Today, p.CreationDate) &amp;lt; 5     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;select &lt;/span&gt;p; &lt;/div&gt;  &lt;p&gt;The following example shows how a user defined function defined in SQL Server can be mapped: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; &lt;span class="type"&gt;MyCustomFunctions      &lt;br&gt;&lt;/span&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"SqlServer"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"MyFunction"&lt;/span&gt;)]     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;Int32&lt;/span&gt;? MyFunction(&lt;span class="keyword"&gt;string&lt;/span&gt; myArg)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;throw&lt;/span&gt; new &lt;span class="type"&gt;NotSupportedException&lt;/span&gt;(&lt;span class="stringliteral"&gt;"Direct calls not supported"&lt;/span&gt;);&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;} &lt;/div&gt;  &lt;h4&gt;Convention based function name &lt;/h4&gt;  &lt;p&gt;We can establish that by convention the name of the CLR function defines the value of the functionName parameter. That makes the functionName parameter in the EdmFunctionAttribute optional. &lt;/p&gt;  &lt;h4&gt;EdmFunctionNamespaceAttribute&lt;/h4&gt;  &lt;p&gt;To avoid having to always specify the namespaceName for each function, we define a new class-level attribute named &lt;b&gt;EdmFunctionNamespaceAttribute &lt;/b&gt;that would define the namespace mapping globally for a given class: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;public &lt;/span&gt;EdmFunctionNamespaceAttribute(&lt;span class="keyword"&gt;string &lt;/span&gt;namespaceName) &lt;/div&gt;  &lt;p&gt;Using EdmFunctionNamespaceAttribute and the convention based constructor: &lt;/p&gt;  &lt;div class="codeblock"&gt;[&lt;span class="type"&gt;EdmFunctionNamespace&lt;/span&gt;(&lt;span class="stringliteral"&gt;"EDM"&lt;/span&gt;)]     &lt;br&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; &lt;span class="type"&gt;EdmMethods      &lt;br&gt;&lt;/span&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;]     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;Int32&lt;/span&gt;? DiffYears(&lt;span class="type"&gt;DateTime&lt;/span&gt;? arg1, &lt;span class="type"&gt;DateTime&lt;/span&gt;? arg2)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;throw&lt;/span&gt; EntityUtil.NotSupported(     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Data.Entity.&lt;span class="type"&gt;Strings&lt;/span&gt;.ELinq_EdmFunctionDirectCall);&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;}&lt;/div&gt;  &lt;h4&gt;How it works &lt;/h4&gt;  &lt;p&gt;When a method with the EdmFunction attribute is detected within a LINQ query expression, its treatment is identical to that of a function within an Entity-SQL query. Overload resolution is performed with respect to the EDM types (not CLR types) of the function arguments. Ambiguous overloads, missing functions or lack of overloads result in an exception. In addition, the return type of the method must be validated. If the CLR return type does not have an implicit cast to the appropriate EDM type, the translation will fail. &lt;/p&gt;  &lt;p&gt;Instance methods on the ObjectContext will be supported as well. This allows the method to bootstrap itself and trigger direct evaluation, as in the following example (definition of the method and sample query): &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;public static class&lt;/span&gt; MyObjectContext : ObjectContext     &lt;br&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="comment"&gt;// Method definition&lt;/span&gt;     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"edm"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"floor"&lt;/span&gt;)]     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public &lt;/span&gt;&lt;span class="type"&gt;double&lt;/span&gt;&lt;span class="keyword"&gt;&lt;/span&gt;? Floor(&lt;span class="type"&gt;double&lt;/span&gt;? value)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;span class="keyword"&gt;this&lt;/span&gt;.QueryProvider.Execute&amp;lt;&lt;span class="type"&gt;double&lt;/span&gt;?&amp;gt;(&lt;span class="type"&gt;Expression&lt;/span&gt;.Call(     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="type"&gt;Expression&lt;/span&gt;.Constant(this),     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;span class="type"&gt;MethodInfo&lt;/span&gt;)&lt;span class="type"&gt;MethodInfo&lt;/span&gt;.GetCurrentMethod(),     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="type"&gt;Expression&lt;/span&gt;.Constant(value, &lt;span class="keyword"&gt;typeof&lt;/span&gt;(&lt;span class="type"&gt;double&lt;/span&gt;?))));     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;}     &lt;br&gt;    &lt;br&gt;…     &lt;br&gt;    &lt;br&gt;&lt;span class="comment"&gt;// evaluated in the store! &lt;/span&gt;    &lt;br&gt;context.Floor(0.1);     &lt;br&gt;&lt;/div&gt;  &lt;p&gt;Without the ObjectContext, the function cannot reach the store! To support this style of bootstrapping, the context needs to expose the LINQ query provider. For this reason, we now expose a “QueryProvider” property on the ObjectContext. This provider includes the necessary surface to construct or execute a query given a LINQ expression. &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;public class &lt;/span&gt;&lt;span class="type"&gt;ObjectContext &lt;/span&gt;    &lt;br&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public &lt;/span&gt;&lt;span class="type"&gt;IQueryProvider&lt;/span&gt; QueryProvider { &lt;span class="keyword"&gt;get&lt;/span&gt;; }     &lt;br&gt;} &lt;/div&gt;  &lt;p&gt;If such a method is encountered inline in another query, then we must validate that the instance argument (MethodCallExpression.Object) is the correct context, but the instance is otherwise ignored: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="comment"&gt;// positive &lt;/span&gt;    &lt;br&gt;&lt;span class="keyword"&gt;var &lt;/span&gt;q1 = &lt;span class="keyword"&gt;from &lt;/span&gt;p &lt;span class="keyword"&gt;in &lt;/span&gt;context.Products &lt;span class="keyword"&gt;select &lt;/span&gt;context.Floor(p.Price);     &lt;br&gt;    &lt;br&gt;&lt;span class="comment"&gt;// negative&lt;/span&gt;     &lt;br&gt;&lt;span class="keyword"&gt;var &lt;/span&gt;q2 = &lt;span class="keyword"&gt;from &lt;/span&gt;p &lt;span class="keyword"&gt;in &lt;/span&gt;context.Products &lt;span class="keyword"&gt;select &lt;/span&gt;context2.Floor(p.Price); &lt;/div&gt;  &lt;p&gt;A function proxy can sometimes bootstrap itself without an explicit context, e.g. when an input argument is itself an IQueryable: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;public static class &lt;/span&gt;&lt;span class="type"&gt;SqlFunctions &lt;/span&gt;    &lt;br&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"SqlServer"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"stdev"&lt;/span&gt;)]     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public static&lt;/span&gt; &lt;span class="keyword"&gt;double&lt;/span&gt;? StandardDeviation(&lt;span class="keyword"&gt;this&lt;/span&gt; &lt;span class="type"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span class="keyword"&gt;int&lt;/span&gt;?&amp;gt; source)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;return&lt;/span&gt; source.Provider.Execute&amp;lt;&lt;span class="keyword"&gt;double&lt;/span&gt;?&amp;gt;(&lt;span class="type"&gt;Expression&lt;/span&gt;.Call(     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;span class="type"&gt;MethodInfo&lt;/span&gt;)&lt;span class="type"&gt;MethodInfo&lt;/span&gt;.GetCurrentMethod(),     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="type"&gt;Expression&lt;/span&gt;.Constant(source)));     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;} &lt;/div&gt;  &lt;h4&gt;Nullability considerations &lt;/h4&gt;  &lt;p&gt;Particularly for functions taking collections, we will need to provide overloads for nullable and non-nullable elements. We don’t want to require awkward constructions like: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;var &lt;/span&gt;query = (&lt;span class="keyword"&gt;from &lt;/span&gt;p &lt;span class="keyword"&gt;in &lt;/span&gt;products &lt;span class="keyword"&gt;select &lt;/span&gt;(&lt;span class="keyword"&gt;int&lt;/span&gt;?)p.ReorderLevel).StandardDeviation(); &lt;/div&gt;  &lt;h4&gt;Tool for Generating the Functions &lt;/h4&gt;  &lt;p&gt;We created a simple internal tool that generates the classes that represent all the EDM canonical function and the SQL Server store functions. The tool will take the function definitions from Metadata and generate the appropriate function stubs/implementations. &lt;/p&gt;  &lt;p&gt;The tool will be outside the product and will be run on demand. We expect to make a version of this tool available for provider writers together with the provider samples. &lt;/p&gt;  &lt;h4&gt;Naming &lt;/h4&gt;  &lt;p&gt;The methods will be in the following classes: &lt;/p&gt;  &lt;table class="ms-column4-main"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td class="ms-column4-tl"&gt;&lt;b&gt;Namespace&lt;/b&gt; &lt;/td&gt;        &lt;td class="ms-column4-tl"&gt;&lt;b&gt;Class name&lt;/b&gt; &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td class="ms-column4-left"&gt;         &lt;br&gt;System.Data.Objects           &lt;br&gt;&lt;/td&gt;        &lt;td class="ms-column4-left"&gt;         &lt;br&gt;EntityFunctions &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td class="ms-column4-left"&gt;         &lt;br&gt;System.Data.Objects.SqlClient           &lt;br&gt;&lt;/td&gt;        &lt;td class="ms-column4-left"&gt;         &lt;br&gt;SqlFunctions &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;i&gt;Note: The equivalent class in LINQ to SQL is System.Data.Linq.SqlClient.SqlMethods. &lt;/i&gt;&lt;/p&gt;  &lt;p&gt;The method names will correspond to the name of the EDM/SQL function they represent. The argument names will correspond to the argument names of the EDM/SQL functions as retrieved by the metadata. &lt;/p&gt;  &lt;p&gt;The recommendation for provider writers will be to include a similar static class in a namespace of the following form: &lt;/p&gt;  &lt;p&gt;&lt;i&gt;System.Data.Objects.[Standard provider namespace].[Standard provider prefix]Functions &lt;/i&gt;&lt;/p&gt;  &lt;h4&gt;Overloads and Implementation &lt;/h4&gt;  &lt;h5&gt;Non-aggregate Functions &lt;/h5&gt;  &lt;p&gt;For each non-aggregate function we create an overload with all inputs type as nullable of the CLR equivalent of their EDM primitive type, and the return type nullable of the CLR equivalent of their EDM primitive type.&lt;/p&gt;  &lt;p&gt;The implementation of the functions (what gets executed if the function is invoked outside an expression tree) will be to throw a NotSupportedException. &lt;/p&gt;  &lt;p&gt;Example: &lt;/p&gt;  &lt;div class="codeblock"&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; &lt;span class="type"&gt;EntityFunctions      &lt;br&gt;&lt;/span&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"EDM"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"DiffYears"&lt;/span&gt;)]     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;Int32&lt;/span&gt;? DiffYears(&lt;span class="type"&gt;DateTime&lt;/span&gt;? arg1, &lt;span class="type"&gt;DateTime&lt;/span&gt;? arg2)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;throw&lt;/span&gt; &lt;span class="type"&gt;EntityUtil&lt;/span&gt;.NotSupported(System.Data.Entity.&lt;span class="type"&gt;Strings&lt;/span&gt;.ELinq_EdmFunctionDirectCall);&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;} &lt;span class="keyword"&gt;     &lt;br&gt;      &lt;br&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; &lt;span class="type"&gt;SqlFunctions      &lt;br&gt;&lt;/span&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"SqlServer"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"DiffYears"&lt;/span&gt;)]     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;Int32&lt;/span&gt;? DiffYears(&lt;span class="type"&gt;DateTime&lt;/span&gt;? arg1, &lt;span class="type"&gt;DateTime&lt;/span&gt;? arg2)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;throw&lt;/span&gt; &lt;span class="type"&gt;EntityUtil&lt;/span&gt;.NotSupported(System.Data.Entity.&lt;span class="type"&gt;Strings&lt;/span&gt;.ELinq_EdmFunctionDirectCall);&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;} &lt;/div&gt;  &lt;h5&gt;Aggregate Functions &lt;/h5&gt;  &lt;p&gt;For each aggregate function we will provide two overloads, one with IEnumerable&amp;lt;Nullable&amp;lt;T&amp;gt;&amp;gt; and another one with IEnumerable&amp;lt;T&amp;gt;, where T is the CLR equivalent of the EDM primitive type of the input. The implementations of these will check whether the input is IQueryable in which case it will implement the self-bootstrapping. &lt;/p&gt;  &lt;p&gt;Example: &lt;/p&gt;  &lt;div class="codeblock"&gt;[&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"EDM"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"VARP"&lt;/span&gt;)]     &lt;br&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;double&lt;/span&gt;? VarP(&lt;span class="type"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span class="keyword"&gt;int&lt;/span&gt;&amp;gt; arg1)     &lt;br&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="type"&gt;ObjectQuery&lt;/span&gt;&amp;lt;&lt;span class="keyword"&gt;int&lt;/span&gt;&amp;gt; objectQuerySource = source &lt;span class="keyword"&gt;as&lt;/span&gt; &lt;span class="type"&gt;ObjectQuery&lt;/span&gt;&amp;lt;&lt;span class="keyword"&gt;int&lt;/span&gt;&amp;gt;;     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;if&lt;/span&gt; (objectQuerySource != &lt;span class="keyword"&gt;null&lt;/span&gt;)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;return&lt;/span&gt; ((&lt;span class="type"&gt;IQueryable&lt;/span&gt;)objectQuerySource).Provider.Execute&amp;lt;&lt;span class="keyword"&gt;double&lt;/span&gt;?&amp;gt;(&lt;span class="type"&gt;Expression&lt;/span&gt;.Call(     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;span class="type"&gt;MethodInfo&lt;/span&gt;)&lt;span class="type"&gt;MethodInfo&lt;/span&gt;.GetCurrentMethod(),     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="type"&gt;Expression&lt;/span&gt;.Constant(source)));     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;throw&lt;/span&gt; &lt;span class="type"&gt;EntityUtil&lt;/span&gt;.NotSupported(System.Data.Entity.&lt;span class="type"&gt;Strings&lt;/span&gt;.ELinq_EdmFunctionDirectCall);&amp;nbsp; &lt;br&gt;}     &lt;br&gt;    &lt;br&gt;[&lt;span class="type"&gt;EdmFunction&lt;/span&gt;(&lt;span class="stringliteral"&gt;"EDM"&lt;/span&gt;, &lt;span class="stringliteral"&gt;"VARP"&lt;/span&gt;)]     &lt;br&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="keyword"&gt;double&lt;/span&gt;? VarP(&lt;span class="type"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span class="keyword"&gt;int&lt;/span&gt;?&amp;gt; arg1)     &lt;br&gt;{     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="type"&gt;ObjectQuery&lt;/span&gt;&amp;lt;&lt;span class="keyword"&gt;int?&lt;/span&gt;&amp;gt; objectQuerySource = source &lt;span class="keyword"&gt;as&lt;/span&gt; &lt;span class="type"&gt;ObjectQuery&lt;/span&gt;&amp;lt;&lt;span class="keyword"&gt;int?&lt;/span&gt;&amp;gt;;     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;if&lt;/span&gt; (objectQuerySource != &lt;span class="keyword"&gt;null&lt;/span&gt;)     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;return&lt;/span&gt; ((&lt;span class="type"&gt;IQueryable&lt;/span&gt;)objectQuerySource).Provider.Execute&amp;lt;&lt;span class="keyword"&gt;double&lt;/span&gt;?&amp;gt;(&lt;span class="type"&gt;Expression&lt;/span&gt;.Call(     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;span class="type"&gt;MethodInfo&lt;/span&gt;)&lt;span class="type"&gt;MethodInfo&lt;/span&gt;.GetCurrentMethod(),     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="type"&gt;Expression&lt;/span&gt;.Constant(source)));     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="keyword"&gt;throw&lt;/span&gt; &lt;span class="type"&gt;EntityUtil&lt;/span&gt;.NotSupported(System.Data.Entity.&lt;span class="type"&gt;Strings&lt;/span&gt;.ELinq_EdmFunctionDirectCall);&amp;nbsp; &lt;br&gt;}     &lt;br&gt;&lt;/div&gt;  &lt;p&gt;The Entity Framework team would love to hear your comments.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;a href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;Alex James&lt;/a&gt;&lt;/b&gt;&amp;nbsp; &lt;br&gt;Program Manager,     &lt;br&gt;Entity Framework Team&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;This post is part of the transparent design exercise in the Entity Framework Team. To understand how it works and how your feedback will be used please look at &lt;a href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx" mce_href="http://blogs.msdn.com/efdesign/archive/2008/06/23/transparency-in-the-design-process.aspx"&gt;this post&lt;/a&gt;.&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8962709" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework/default.aspx">Entity Framework</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Linq+to+Entities/default.aspx">Linq to Entities</category><category domain="http://blogs.msdn.com/efdesign/archive/tags/Entity+Framework+4/default.aspx">Entity Framework 4</category></item></channel></rss>