2016-04-28 59 views
0

如何创建存储过程以执行与此代码相同的功能?如何创建存储过程以更新C#中的多行

string sql = "Update Product set ProductName='" + Product.Name + "' where ProductId=" + Product.Id + ""; 

foreach (var item in Product.pros) 
{ 
    sql += "Update ProductProperties set PropertyValue ='" + item.PropertyValue + "' where PropertyId =" + item.PropertyId + " and ProductId =" + Product.Id + ""; 
} 

db.Database.ExecuteSqlCommand(sql); 
+2

也许去看看关于存储过程?这看起来很基本,几乎是本书的第1页。 – DavidG

+1

“为我翻译这段代码”对Stack Overflow来说不是一个合适的“问题”。 – Blorgbeard

+0

Blorgbeard,在我的代码中,我通过集合循环来为集合中的每个项目创建更新语句。我的问题是我怎样才能做到与存储过程一样...我的困惑是如何使存储过程和循环....谢谢 – Lucy

回答

1

你想要的是一个table valued parameter。我们过去常常做一些非常丑陋的事情,比如将逗号分隔的字符串传递给过程并将其拆分,以便我们不必进行多个过程调用,或者传递XML。这在2008年推出,而且更容易。

在你的数据库,你会声明类型:

CREATE TYPE ProductUpdateTableType AS TABLE 
    (productId int, propertyId int, propertyValue varchar(20)); 

(只是猜测/组成的数据类型。)

然后在你的存储过程,你会使用这样的参数:

CREATE PROCEDURE UpdateProducts 
    @productUpdates ProductUpdateTableType READONLY 
AS 
UPDATE products set propertyValue = updates.propertyValue 
FROM 
    ProductProperties product 
    JOIN @productUpdates updates 
     on product.productId = updates.productId 
     and product.propertyId = updates.propertyId 

您使用的参数就像是表格一样。

在C#端,您需要创建一个DataTable并添加与其表类型匹配的列。然后你会添加包含单个值的行。我通常创建一个类是这样的:

public class ProductUpdateParameter : DataTable 
{ 
    public ProductUpdateParameter() 
    { 
     Columns.Add("productId", typeof (int)); 
     Columns.Add("propertyId", typeof (int)); 
     Columns.Add("propertyValue", typeof (string)); 
     Columns[2].MaxLength = 20; 
    } 

    public void AddProductUpdate(int productId, int propertyId, string propertyValue) 
    { 
     Rows.Add(productId, propertyId, propertyValue); 
    } 
} 

您创建的ProductUpdateParameter一个实例的方式,并根据需要添加尽可能多的项目。 然后,呼唤你的过程时,你会做这样的:

var updateParameter = new SqlParameter("@productUpdates", SqlDbType.Structured); 
    updateParameter.TypeName = "dbo.ProductUpdateTableType"; 
    updateParameter.Value = [your data table] 

该参数然后添加到您的SqlCommand并执行它。