2010-10-13 50 views
1

我使用的是Visual Studio 2010,C#,Entity Framework 4和Oracle 10g。如何在實體框架4的LINQ表達式中執行Oracle函數?

我需要能夠返回數據庫函數的結果作爲匿名類型的標量屬性。

我的Oracle模式有兩個表,PARENT和CHILD和一個函數FNC_ADD。我使用Visual Studio ADO.NET實體數據模型模板創建了一個實體模型,包括表格和函數。

我.edmx文件的StorageModels部分看起來是這樣的:

<!-- SSDL content --> 
<edmx:StorageModels> 
<Schema Namespace="LINQtest2Model.Store" Alias="Self" Provider="Devart.Data.Oracle" ProviderManifestToken="ORA" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl"> 
    <EntityContainer Name="LINQtest2ModelStoreContainer"> 
     <EntitySet Name="CHILD" EntityType="LINQtest2Model.Store.CHILD" store:Type="Tables" Schema="LINQ_TEST" /> 
     <EntitySet Name="PARENT" EntityType="LINQtest2Model.Store.PARENT" store:Type="Tables" Schema="LINQ_TEST" /> 
     <AssociationSet Name="LINQ_TEST_FK_PARENT" Association="LINQtest2Model.Store.LINQ_TEST_FK_PARENT"> 
     <End Role="PARENT" EntitySet="PARENT" /> 
     <End Role="CHILD" EntitySet="CHILD" /> 
     </AssociationSet> 
    </EntityContainer> 
    <EntityType Name="CHILD"> 
     <Key> 
     <PropertyRef Name="CHILD_ID" /> 
     </Key> 
     <Property Name="CHILD_ID" Type="decimal" Nullable="false" /> 
     <Property Name="PARENT_ID" Type="decimal" Nullable="false" /> 
     <Property Name="F_NAME" Type="VARCHAR2" MaxLength="20" /> 
     <Property Name="L_NAME" Type="VARCHAR2" MaxLength="50" /> 
     <Property Name="CREATE_DATE" Type="DATE" Nullable="false" /> 
    </EntityType> 
    <EntityType Name="PARENT"> 
     <Key> 
     <PropertyRef Name="PARENT_ID" /> 
     </Key> 
     <Property Name="PARENT_ID" Type="decimal" Nullable="false" /> 
     <Property Name="F_NAME" Type="VARCHAR2" MaxLength="20" /> 
     <Property Name="L_NAME" Type="VARCHAR2" MaxLength="50" /> 
     <Property Name="CREATE_DATE" Type="DATE" Nullable="false" /> 
    </EntityType> 
    <Association Name="LINQ_TEST_FK_PARENT"> 
     <End Role="PARENT" Type="LINQtest2Model.Store.PARENT" Multiplicity="1"> 
     <OnDelete Action="Cascade" /> 
     </End> 
     <End Role="CHILD" Type="LINQtest2Model.Store.CHILD" Multiplicity="*" /> 
     <ReferentialConstraint> 
     <Principal Role="PARENT"> 
      <PropertyRef Name="PARENT_ID" /> 
     </Principal> 
     <Dependent Role="CHILD"> 
      <PropertyRef Name="PARENT_ID" /> 
     </Dependent> 
     </ReferentialConstraint> 
    </Association> 
    <Function Name="FNC_ADD" ReturnType="decimal" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="LINQ_TEST"> 
     <Parameter Name="V1" Type="decimal" Mode="In" /> 
     <Parameter Name="V2" Type="decimal" Mode="In" /> 
    </Function> 
    </Schema></edmx:StorageModels> 

我創建了一個擴展方法定義看起來像這樣的實體數據模型的功能:

public partial class LINQtest2Entities 
{ 
    [EdmFunction("LINQtest2Model", "FNC_ADD")] 
    public decimal FNC_ADD(decimal V1, decimal V2) 
    { 
     // don’t need to implement the function 
     throw new ApplicationException(); 
    } 
} 

我在像這樣的LINQ表達式中調用函數:

using (var context = new LINQtest2Entities()) 
{ 
    var parents = from p in context.PARENTs 
        select new 
        { 
         children = from c in p.Children 
           select new 
           { 
            p.PARENT_ID, 
            c.CHILD_ID, 
            a = context.FNC_ADD(p.PARENT_ID, c.CHILD_ID) 
           } 
        }; 

    foreach (var parent in parents) 
    { 
     foreach (var child in parent.children) 
     { 
      Console.WriteLine("P {0} C {1} A {2}", child.PARENT_ID, child.CHILD_ID, child.a); 
     } 
    } 
} 

Everything compi萊正確的,但是當我運行的代碼我得到這個:

The specified method 'System.Decimal FNC_ADD(System.Decimal, System.Decimal)' on the type 'LINQtest2.LINQtest2Entities' cannot be translated into a LINQ to Entities store expression.

我在做什麼錯?

+1

是否解決了您的問題?我知道這是一箇舊帖子,但提出的解決方案不適用於我的應用程序。雖然它調用函數,但是在聲明「foreach(var parent in parents)」中,它拋出了該函數中拋出的異常,即ApplicationException – 2011-06-16 13:43:23

回答

3

您的名字空間arg至EdmFunctionAttribute看起來可疑。這看起來像CLR類型,而不是商店空間。 This blog post可能會幫助您解決這個問題。

+1

該博客帖子正是我所需要的。 namespaceName應該是LINQtest2Model.Store。 – 2010-10-14 13:58:23

3

使用Model.Store命名空間:

public partial class LINQtest2Entities 
{ 
    [EdmFunction("LINQtest2Model.Store", "FNC_ADD")] 
    public decimal FNC_ADD(decimal V1, decimal V2) 
    { 
     // don’t need to implement the function 
     throw new ApplicationException(); 
    } 
}

如果您所提供的名稱空間已正確一切工作順利進行。