2013-09-21 39 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"); 
}