2010-05-10 38 views
5

有沒有好的方法來利用EdmFunctionAttribute而不引入對實體框架/ System.Data.Entity.dll的依賴?使用EdmFunctionAttribute而不暴露實體框架依賴性/實現細節?

我想我可以有一個方法和一個具體實現的接口,實現該方法使用EdmFunctionAttribute將其映射到數據庫函數。

我在一個程序集中定義了上下文接口IMyContext,另一個程序集中的實體框架實現MyContext

public interface IMyContext 
{ 
    double SomeFunction(double first, double second); 

    // other interface details here 
} 

public partial class MyContext : IMyContext 
{ 
    [EdmFunction("MyNamespace", "MyDatabaseFunction")] 
    public double SomeFunction(double first, double second) 
    { 
     throw new NotSupportedException("This method may only be called as part of a LINQ expression."); 
    } 

    // rest of interface implementation here 
} 

我使用一個工廠(使用StructureMap幕後),以獲得上下文實例作爲接口類型:

using (IMyContext context = ContextFactory.GetNewContext()) 
{ 
    var results = context.Table.Select(t => context.SomeFunction(t.Col1, t.Col2)).ToList(); 
} 

這將引發NotSupportException說,LINQ到實體無法識別方法「 Double SomeFunction(Double,Double)'。

如果我投的背景下,以具體落實

using (MyContext context = ContextFactory.GetNewContext() as MyContext) 
{ 
    ... 
} 

然後它的工作原理,但隨後我要求指定的具體實施,這是我不想做的事。

該函數不一定是上下文類的成員,我只是把它放在那裏進行探索。

+0

我正面臨着同樣的情況。我也希望EdmFunctionAttribute在通過接口引用進行訪問時得到解決,但無濟於事。使用多個上下文(多個數據庫)時,它變得更加困難。 – kdawg 2011-05-17 18:39:49

+0

對於它的價值,我無法解決這個問題,並且不得不在我的Repository(Context的具體實現)上敲擊DB函數,這意味着所有函數調用都必須駐留在我的Repository類中 - 即:my客戶端代碼無法直接訪問它。我對此並不感到興奮,但它起作用(並強制查詢代碼駐留在Repository中,有些人會認爲它屬於它的位置)。 – kdawg 2011-05-17 18:49:23

回答

0

這是不可能的,因爲Linq查詢生成器將調查接口類型,而不是具體類。表達式樹將包含接口方法的方法引用,並且當您調查方法的屬性時,它不會返回任何屬性。

您可以創建一個表達式訪問器並訪問您的表達式樹並將其類型從接口更改爲具體類型。

TypeReplacer tr = new TypeReplacer(); 
tr.Visit(ex); 

class TypeReplacer: ExpressionVisitor{ 
    protected override MethodCallExpression MethodCall(MethodCallExpression exp) 
    { 
     // compare exp.Method and 
     // replace it with concrete Type's method 
     return exp; 
    } 
} 
+0

對不起,您的回答並不能解決問題中尚未實現的任何內容。您的解決方案仍然需要引用具體的上下文類而不是上下文接口。 – GWB 2011-07-19 18:58:28

+0

我已經更新了我的答案。 – 2011-07-24 04:54:09

相關問題