简体   繁体   English

如何使用 DbContext.Database.SqlQuery<TElement> (sql, params) 与存储过程? EF Code First CTP5

[英]How to use DbContext.Database.SqlQuery<TElement>(sql, params) with stored procedure? EF Code First CTP5

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:起初我尝试使用SqlParameter对象作为参数,但这不起作用并抛出了一个SqlException并显示以下消息:

Procedure or function 'mySpName' expects parameter '@param1', which was not supplied.过程或函数“mySpName”需要未提供的参数“@param1”。

So my question is how you can use this method with a stored procedure that expects parameters?所以我的问题是如何将此方法与需要参数的存储过程一起使用?

Thanks.谢谢。

You should supply the SqlParameter instances in the following way:您应该通过以下方式提供 SqlParameter 实例:

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

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

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

This solution is (only) for SQL Server 2005此解决方案(仅)适用于 SQL Server 2005

You guys are lifesavers, but as @Dan Mork said, you need to add EXEC to the mix.你们是救星,但正如@Dan Mork 所说,您需要将 EXEC 添加到组合中。 What was tripping me up was:绊倒我的是:

  • 'EXEC ' before the Proc Name 'EXEC' 在 Proc 名称之前
  • 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)
);
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();
}

Most answers are brittle because they rely on the order of the SP's parameters.大多数答案都很脆弱,因为它们依赖于 SP 参数的顺序。 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为了在调用你的 SP 时使用 Named params,而不用担心参数的顺序

Using SQL Server named parameters with ExecuteStoreQuery and ExecuteStoreCommand 将 SQL Server 命名参数与 ExecuteStoreQuery 和 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.不依赖于连接字符串,也不依赖于 SP 中定义的参数顺序。

Eg:例如:

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)
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();

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.我喜欢它,因为我只是加入了 Guids 和 Datetimes,而 SqlQuery 会为我执行所有格式设置。

@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 @Tom Halladay 的回答是正确的,提到您还应该检查空值并发送 DbNullable 如果 params 为空,因为您会得到类似的异常

The parameterized query '...' expects the parameter '@parameterName', which was not supplied.参数化查询“...”需要未提供的参数“@parameterName”。

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 ) (该方法的功劳转到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)

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当我调用一个带有两个输入参数并使用 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 : It looks like with SQL SERVER 2005 missing EXEC keyword is creating problem.更新:看起来 SQL SERVER 2005 缺少 EXEC 关键字正在产生问题。 So to allow it to work with all SQL SERVER versions I updated my answer and added EXEC in below line所以为了让它适用于所有 SQL SERVER 版本,我更新了我的答案并在下面的行中添加了EXEC

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

I did mine with EF 6.x like this:我用 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 some people get burned doing this to their variable不要在 sqlparameter 上加倍,有些人会对他们的变量这样做

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM