如何将 DbContext.Database.SqlQuery(sql, params) 与存储过程一起使用? EF 代码优先 CTP5

发布于 2024-10-15 15:30:42 字数 367 浏览 1 评论 0原文

我有一个具有三个参数的存储过程,我一直在尝试使用以下内容返回结果:

context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);

起初我尝试使用 SqlParameter 对象作为参数,但这不起作用并引发了SqlException 并显示以下消息:

过程或函数“mySpName”需要参数“@param1”,但未提供该参数。

所以我的问题是如何将此方法与需要参数的存储过程一起使用?

谢谢。

I have a stored procedure that has three parameters and I've been trying to use the following to return the results:

context.Database.SqlQuery<myEntityType>("mySpName", param1, param2, param3);

At first I tried using SqlParameter objects as the params but this didn't work and threw a SqlException with the following message:

Procedure or function 'mySpName' expects parameter '@param1', which was not supplied.

So my question is how you can use this method with a stored procedure that expects parameters?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

九八野马 2024-10-22 15:30:43

您应该通过以下方式提供 SqlParameter 实例:

context.Database.SqlQuery<myEntityType>(
    "mySpName @param1, @param2, @param3",
    new SqlParameter("param1", param1),
    new SqlParameter("param2", param2),
    new SqlParameter("param3", param3)
);

You should supply the SqlParameter instances in the following way:

context.Database.SqlQuery<myEntityType>(
    "mySpName @param1, @param2, @param3",
    new SqlParameter("param1", param1),
    new SqlParameter("param2", param2),
    new SqlParameter("param3", param3)
);
懒的傷心 2024-10-22 15:30:43

另外,您可以使用“sql”参数作为格式说明符:

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)

Also, you can use the "sql" parameter as a format specifier:

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", param1)
遇到 2024-10-22 15:30:43

这个解决方案(仅)适用于 SQL Server 2005

你们是救星,但正如 @Dan Mork 所说,您需要将 EXEC 添加到其中。令我困惑的是:

  • 'EXEC ' 在 Proc 名称之前
  • 参数之间的逗号
  • 砍掉参数上的 '@'
    定义(但不确定该位是必需的)。

:

context.Database.SqlQuery<EntityType>(
    "EXEC ProcName @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);

This solution is (only) for SQL Server 2005

You guys are lifesavers, but as @Dan Mork said, you need to add EXEC to the mix. What was tripping me up was:

  • 'EXEC ' before the Proc Name
  • Commas in between Params
  • Chopping off '@' on the Param
    Definitions (not sure that bit is required though).

:

context.Database.SqlQuery<EntityType>(
    "EXEC ProcName @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);
余厌 2024-10-22 15:30:43
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
        new object[] { param1, param2, param3 });

using (var context = new MyDataContext())
{
    return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
            new object[] { param1, param2, param3 })
        .ToList();
}

using (var context = new MyDataContext())
{
    object[] parameters =  { param1, param2, param3 };

    return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
            parameters)
        .ToList();
}

using (var context = new MyDataContext())
{  
    return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
            param1, param2, param3)
        .ToList();
}
return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
        new object[] { param1, param2, param3 });

Or

using (var context = new MyDataContext())
{
    return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
            new object[] { param1, param2, param3 })
        .ToList();
}

Or

using (var context = new MyDataContext())
{
    object[] parameters =  { param1, param2, param3 };

    return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
            parameters)
        .ToList();
}

Or

using (var context = new MyDataContext())
{  
    return context.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
            param1, param2, param3)
        .ToList();
}
羁〃客ぐ 2024-10-22 15:30:43

大多数答案都很脆弱,因为它们依赖于 SP 参数的顺序。最好命名存储过程的参数并为其提供参数化值。

为了在调用 SP 时使用命名参数,而不用担心参数的顺序

将 SQL Server 命名参数与 ExecuteStoreQuery 和 ExecuteStoreCommand 结合使用

描述最佳方法。比 Dan Mork 的答案更好。

  • 不依赖于连接字符串,也不依赖于 SP 中定义的参数顺序。

例如:

var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param";
var sqlParams = new[]{
   new SqlParameter("name_param", "Josh"),
   new SqlParameter("age_param", 45)
};

context.Database.SqlQuery<myEntityType>(cmdText, sqlParams)

Most answers are brittle because they rely on the order of the SP's parameters. Better to name the Stored Proc's params and give parameterized values to those.

In order to use Named params when calling your SP, without worrying about the order of parameters

Using SQL Server named parameters with ExecuteStoreQuery and ExecuteStoreCommand

Describes the best approach. Better than Dan Mork's answer here.

  • Doesn't rely on concatenating strings, and doesn't rely on the order of parameters defined in the SP.

E.g.:

var cmdText = "[DoStuff] @Name = @name_param, @Age = @age_param";
var sqlParams = new[]{
   new SqlParameter("name_param", "Josh"),
   new SqlParameter("age_param", 45)
};

context.Database.SqlQuery<myEntityType>(cmdText, sqlParams)
隱形的亼 2024-10-22 15:30:43
db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()

db.Database.SqlQuery<myEntityType>(
    "exec GetNewSeqOfFoodServing @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);

var cmdText = "exec [DoStuff] @Name = @name_param, @Age = @age_param";
var @params = new[]{
   new SqlParameter("name_param", "Josh"),
   new SqlParameter("age_param", 45)
};

db.Database.SqlQuery<myEntityType>(cmdText, @params)

db.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()

or

db.Database.SqlQuery<myEntityType>(
    "exec GetNewSeqOfFoodServing @param1, @param2", 
    new SqlParameter("param1", param1), 
    new SqlParameter("param2", param2)
);

or

var cmdText = "exec [DoStuff] @Name = @name_param, @Age = @age_param";
var @params = new[]{
   new SqlParameter("name_param", "Josh"),
   new SqlParameter("age_param", 45)
};

db.Database.SqlQuery<myEntityType>(cmdText, @params)

or

db.Database.SqlQuery<myEntityType>("mySpName {0}, {1}, {2}",
new object[] { param1, param2, param3 }).ToList();
╰つ倒转 2024-10-22 15:30:43

我使用这种方法:

var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);

我喜欢它,因为我只需放入 Guid 和 Datetimes,SqlQuery 就会为我执行所有格式设置。

I use this method:

var results = this.Database.SqlQuery<yourEntity>("EXEC [ent].[GetNextExportJob] {0}", ProcessorID);

I like it because I just drop in Guids and Datetimes and SqlQuery performs all the formatting for me.

锦上情书 2024-10-22 15:30:43

@Tom Halladay 的答案是正确的,提到您还应该检查 null 值并在 params 为 null 时发送 DbNullable ,因为您会得到类似

参数化查询 '...' 需要参数 '@parameterName' 的异常,没有提供。

这样的东西帮助了我

public static object GetDBNullOrValue<T>(this T val)
{
    bool isDbNull = true;
    Type t = typeof(T);

    if (Nullable.GetUnderlyingType(t) != null)
        isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
    else if (t.IsValueType)
        isDbNull = false;
    else
        isDbNull = val == null;

    return isDbNull ? DBNull.Value : (object) val;
}

(该方法的功劳转到https://stackoverflow.com /users/284240/tim-schmelter

然后像这样使用它:

new SqlParameter("@parameterName", parameter.GetValueOrDbNull())

或其他解决方案,更简单,但不通用是:

new SqlParameter("@parameterName", parameter??(object)DBNull.Value)

@Tom Halladay's answer is correct with the mention that you shopuld also check for null values and send DbNullable if params are null as you would get an exception like

The parameterized query '...' expects the parameter '@parameterName', which was not supplied.

Something like this helped me

public static object GetDBNullOrValue<T>(this T val)
{
    bool isDbNull = true;
    Type t = typeof(T);

    if (Nullable.GetUnderlyingType(t) != null)
        isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
    else if (t.IsValueType)
        isDbNull = false;
    else
        isDbNull = val == null;

    return isDbNull ? DBNull.Value : (object) val;
}

(credit for the method goes to https://stackoverflow.com/users/284240/tim-schmelter)

Then use it like:

new SqlParameter("@parameterName", parameter.GetValueOrDbNull())

or another solution, more simple, but not generic would be:

new SqlParameter("@parameterName", parameter??(object)DBNull.Value)
情释 2024-10-22 15:30:43

我用 EF 6.x 做了这样的事情:

using(var db = new ProFormDbContext())
            {
                var Action = 1; 
                var xNTID = "A239333";

                var userPlan = db.Database.SqlQuery<UserPlan>(
                "AD.usp_UserPlanInfo @Action, @NTID", //, @HPID",
                new SqlParameter("Action", Action),
                new SqlParameter("NTID", xNTID)).ToList();


            }

Don’t double up on sqlparameter 有些人对他们的变量这样做会被烧伤

var Action = new SqlParameter("@Action", 1);  // Don't do this, as it is set below already.

I did mine with EF 6.x like this:

using(var db = new ProFormDbContext())
            {
                var Action = 1; 
                var xNTID = "A239333";

                var userPlan = db.Database.SqlQuery<UserPlan>(
                "AD.usp_UserPlanInfo @Action, @NTID", //, @HPID",
                new SqlParameter("Action", Action),
                new SqlParameter("NTID", xNTID)).ToList();


            }

Don't double up on sqlparameter some people get burned doing this to their variable

var Action = new SqlParameter("@Action", 1);  // Don't do this, as it is set below already.
胡大本事 2024-10-22 15:30:43

当我调用一个带有两个输入参数并使用 SELECT 语句返回 3 个值的存储过程时,我遇到了相同的错误消息,并且我在 EF Code First Approach

 SqlParameter @TableName = new SqlParameter()
        {
            ParameterName = "@TableName",
            DbType = DbType.String,
            Value = "Trans"
        };

SqlParameter @FieldName = new SqlParameter()
        {
            ParameterName = "@FieldName",
            DbType = DbType.String,
            Value = "HLTransNbr"
        };


object[] parameters = new object[] { @TableName, @FieldName };

List<Sample> x = this.Database.SqlQuery<Sample>("EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();


public class Sample
{
    public string TableName { get; set; }
    public string FieldName { get; set; }
    public int NextNum { get; set; }
}

UPDATE 中解决了如下问题:与 SQL SERVER 2005 一样,缺少 EXEC 关键字会产生问题。因此,为了允许它与所有 SQL SERVER 版本一起使用,我更新了我的答案并在下面的行中添加了 EXEC

 List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", param).ToList();

I had the same error message when I was working with calling a stored procedure that takes two input parameters and returns 3 values using SELECT statement and I solved the issue like below in EF Code First Approach

 SqlParameter @TableName = new SqlParameter()
        {
            ParameterName = "@TableName",
            DbType = DbType.String,
            Value = "Trans"
        };

SqlParameter @FieldName = new SqlParameter()
        {
            ParameterName = "@FieldName",
            DbType = DbType.String,
            Value = "HLTransNbr"
        };


object[] parameters = new object[] { @TableName, @FieldName };

List<Sample> x = this.Database.SqlQuery<Sample>("EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", parameters).ToList();


public class Sample
{
    public string TableName { get; set; }
    public string FieldName { get; set; }
    public int NextNum { get; set; }
}

UPDATE: It looks like with SQL SERVER 2005 missing EXEC keyword is creating problem. So to allow it to work with all SQL SERVER versions I updated my answer and added EXEC in below line

 List<Sample> x = this.Database.SqlQuery<Sample>(" EXEC usp_NextNumberBOGetMulti @TableName, @FieldName", param).ToList();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文