2013-09-21 42 views
0

給定一個名稱,我需要檢查在我們的EDMX中是否存在具有該名稱的存儲過程,然後使用其參數運行它。動態調用實體框架中的存儲過程

被調用的sproc通過context.Database.SqlQuery找到,並且通過運行已知的sproc通過context.GetQueryParameters(string QueryName)來查找參數。

我剩下一個sproc名稱,它是SQL參數的名稱和類型。

非常感謝您的幫助!這已經殺了我...

+0

聽起來像你會更好地恢復到ADO.NET提供商來弄清楚。並不是說這是不可能的,但是這樣做的努力將會是一點也不會有好處的。 –

+0

是的,不使用EF會容易得多,並且只需親自查看數據庫即可獲取並運行存儲過程。 – gunr2171

+0

謝謝!我一整天都在強調這一點,最後放棄並像你們所說的那樣直接進入數據庫。這似乎很不雅,因爲我留下了一個數據集(來自sqldataadapter)和一個方法使用的新連接字符串。 –

回答

1

很難準確猜測你使用的是什麼,但基於你使用GetQueryParameters作爲proc名稱,我猜這是否適用於不同的查詢/搜索。

如果這些都返回相同的類型(搜索結果),並且您希望在EF中執行此操作的原因是強打字,則可以執行以下操作: (示例在EF5和LinqPad中使用測試上下文)

using (var context = new TestEntities()) 
{ 
    string procname = "GetPrograms"; 
    // context has method GetPrograms(int? id) 

    // Method1 - use the method on the context 
    // This won't work dynamically 
    IEnumerable<GetPrograms_Result> result1 = context.GetPrograms(4); 
    result1.Dump("Method1"); 

    // Method2 - use reflection to get and use the method on the context 
    // Building your parameters needs to be in the order they are on the method 
    // This gets you an IEnumerable, but not a strongly typed one 

    MethodInfo method = context.GetType().GetMethod(procname); 
    method.GetParameters(); 
    List<object> parameters = new List<object>(); 
    parameters.Add(4); 

    IEnumerable result2 = (IEnumerable) method.Invoke(context,parameters.ToArray()); 
    result2.Dump("Method2"); 

    // Method3 - make a SqlQuery call on a common return type, passing a dynamic list 
    // of SqlParameters. This return type can be but dows not need to be an Entity type 

    var argList = new List<SqlParameter>(); 
    argList.Add(new SqlParameter("@id",4)); 

    object[] prm = argList.ToArray(); 
    var csv = String.Join(",",argList.Select (l => l.ParameterName)); 

    IEnumerable<GetPrograms_Result> result3 = context.Database.SqlQuery<GetPrograms_Result>("exec " + procname + " " + csv ,prm); 
    result3.Dump("Method3"); 
}