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




value execute (9)

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

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

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

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

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

謝謝。


Answers

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

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

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

entityobject_name.Database.ExecuteSqlCommand(string.Format(@"EXEC sp_name @parameter1='{0}',@path='{2}'", pvalue1, pvalue2));

其中entityobject_name是為實體實例創建的對象: Entity ent=new entity() // ent is entityobject name here


此外,您可以使用“sql”參數作為格式說明符:

context.Database.SqlQuery<MyEntityType>("mySpName @param1 = {0}", 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)

此解決方案(僅)適用於SQL Server 2005

你們是救生員,但正如@丹Mork所說的,你需要將EXEC添加到組合中。 絆倒我的是:

  • Proc名稱前的'EXEC'
  • 逗號在Params之間
  • 在參數定義上砍掉'@'(不確定該位是否是必需的)。

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

我使用這種方法:

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

存儲過程:

(++)

  • 非常靈活
  • 完全控制SQL
  • 可用的最高性能

( - )

  • 需要SQL知識
  • 存儲過程不受源代碼控制
  • 在指定相同的表格和字段名稱時,大量的“重複你自己”。 重命名數據庫實體並在某處丟失對它的某些引用之後破壞應用程序的高可能性。
  • 發展緩慢

ORM:

(+)

  • 快速發展
  • 數據訪問代碼現在在源代碼管理下
  • 您與數據庫中的更改隔離開來。 如果發生這種情況,你只需要在一個地方更新你的模型/映射。

( - )

  • 表現可能會更糟
  • 對ORM產生的SQL沒有或幾乎沒有控制(可能是低效或更壞的錯誤)。 可能需要介入並用自定義存儲過程替換它。 這會使你的代碼變得混亂(某些代碼中的LINQ,代碼中的某些SQL和/或源代碼管理中的數據庫中)。
  • 任何抽像都可能會產生“高層次”的開發人員,他們不知道它是如何工作的

一般的權衡取決於具有很大的靈活性和失去很多時間,而不是限制在你能做的事情上,而是讓它很快完成。

這個問題沒有一般的答案。 這是聖戰的問題。 還取決於手頭的項目和您的需求。 拿起最適合你的東西。







c# sql ado.net linq-to-entities entity-framework-ctp5