c# - statement - sqlquery tolist




如何使用存儲過程使用DbContext.Database.SqlQuery<TElement>(sql,params)? EF Code First CTP5 (7)

我有一個存儲過程有三個參數,我一直試圖使用以下來返回結果:

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

起初,我嘗試使用SqlParameter對像作為參數,但這不起作用,並拋出一個SqlException與下面的消息:

過程或函數'mySpName'需要沒有提供的參數'@ param1'。

所以我的問題是你如何使用這個方法與期望參數的存儲過程?

謝謝。


@Tom Halladay的答案是正確的,提到你shopuld也檢查空值,並發送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://.com/users/284240/tim-schmelter )

然後像這樣使用它:

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

或另一種解決方案,更簡單,但不是通用的將是:

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

大多數答案都是脆弱的,因為它們依賴於SP參數的順序。 更好地命名存儲過程的參數並給這些參數化值。

在調用SP時使用Named參數,而不用擔心參數的順序

使用帶有ExecuteStoreQuery和ExecuteStoreCommand的SQL Server命名參數

介紹最佳方法。 比丹Mork的答案在這裡好。

  • 不依賴連接字符串,也不依賴SP中定義的參數順序。

例如:

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

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

您應該按照以下方式提供SqlParameter實例:

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

我使用這種方法:

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

我喜歡它,因為我只是放在Guid和日期時間,而SqlQuery為我執行所有格式。


當我使用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; }
}

更新 :它看起來像SQL SERVER 2005缺少EXEC關鍵字正在創建問題。 所以為了讓它能夠與所有的SQL SERVER版本一起工作,我更新了我的答案,並在下面添加了EXEC

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

db.Database.SqlQuery<myEntityType>("exec GetNewSeqOfFoodServing @p0,@p1,@p2 ", foods_WEIGHT.NDB_No, HLP.CuntryID, HLP.ClientID).Single()

@ P0,P1 @,@ P2 ......
要么

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

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




entity-framework-ctp5